热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

蚁群算法(ACA)解TSP代码

程序名称:针对TSP组合优化问题人工蚁群算法(ACA_TSP)编译环境:Visua

/***************************************************************
* 程序名称: 针对TSP组合优化问题人工蚁群算法(ACA_TSP)
* 编译环境: Visual C++ 6.0
* 交流方式: Email (junh_cs@126.com)
***************************************************************/
#include
#include
#include
#include
#include
/**************************************************************/
#define CITY_NUM 30 //表示城市数目
#define ANT_NUM 10 //表示蚂蚁数目
#define ITERITIVE_NUM 400 //表示迭代的次数
#define POSITION_DIM 2 //表示城市坐标的维度
#define FCITY_INDEX 0 //用来表示初始城市的下标(目前只能等于0,后期改进)
// 下面的参数选取对结果有很大的影响
#define AILFA 5 //用来表示信息素在计算转移概率的重要性
#define BETA 4 //用来表示能见度(距离信息)在计算转移概率的重要性
#define VOLATIE_FACTOR 0.08 //挥发因子在0到1之间
#define INIT_PHEROMONE 0.1 //每个边的初始信息素含量
/*
//在DATA30.dat上调的参数
#define CITY_NUM 30 //表示城市数目
#define ANT_NUM 10 //表示蚂蚁数目
#define ITERITIVE_NUM 400 //表示迭代的次数
#define POSITION_DIM 2 //表示城市坐标的维度
#define FCITY_INDEX 0 //用来表示初始城市的下标(目前只能等于0,后期改进)
// 下面的参数选取对结果有很大的影响
#define AILFA 4 //用来表示信息素在计算转移概率的重要性
#define BETA 3 //用来表示能见度(距离信息)在计算转移概率的重要性
#define VOLATIE_FACTOR 0.08 //挥发因子在0到1之间
#define INIT_PHEROMONE 0.1 //每个边的初始信息素含量
//0->17->1->9->13->27->6->16->21->11->24->3->7->8->28->15->14->22->20->12->10->4->29->23->5->25->18->26->19->2->0
//total_distance = 420.794632
*/
/**************************************************************/
// 定义个全局变量
double city_pos[CITY_NUM][POSITION_DIM]; //存储city的坐标信息
double pheromone[CITY_NUM][CITY_NUM]; //存储cityA到cityB边的信息素
double city_dis[CITY_NUM][CITY_NUM]; //存储cityA到cityB的距离,即:能见度
int local_road_info[CITY_NUM+1]; //存储此次最好(最短)路径 (默认都是文件读入的编号开始)
int global_road_info[CITY_NUM+1]; //存储此次最好(最短)路径 (默认都是文件读入的编号开始)
double local_road_dis = 9999999999; //存储最好(最短)路径长度
double global_road_dis = 9999999999; //存储最好(最短)路径长度
int tag_old[ANT_NUM][CITY_NUM]; //存储每只蚂蚁走过了哪些路,走过用1,没走过用0
/**************************************************************/
//函数预定义区域
double calculate_Pij(int ant, int cityA, int cityB); //计算ant从cityA转移cityB概率
void initialize(); //初始化环境
void init_tag_old(); //初始化tag_old变量
double odistance(double *a, double *b, int vector_len); //计算两个城市之间距离
void findOneTimeFood(); //模拟人工蚁群一次找食物的过程
void update_pheromone_matrix(); //根据global_road信息跟新信息素
double rand_select_value(double under, double upper); //从[under, upper]之间产生一个随机数
int is_ij_int_global_road(int i, int j); //判断ij在不在全局最优路径中
void search_short_road(); //找到全局最优的路径
void print_cmd(); //在命令行端输出最短路径和路径长度
void print_file(double seconds, char* file_path); //在文件中输出最短路径和路径长度
/**************************************************************/
void main(){
int k;
int i;
FILE *fp;
float x;
float y;
clock_t start;
clock_t end;
srand(time(NULL)); //初始化随机种子
for (k = 0; k <20; k++){
// read city position (x, y)
fp=fopen("DATA30.dat","r");
for(i = 0; i fscanf(fp,"%f %f",&x, &y);
printf("%f, %f\n", x, y);
city_pos[i][0]= x;
city_pos[i][1]= y;
}
fclose(fp);


start=clock(); //记录程序开始运行的时间
initialize();
search_short_road();
end=clock(); //记录程序运行结束的时间
print_file(1.0*(end-start)/1000, "实验结果.txt");
}
}
/**************************************************************
* @function: 初始化变量,构建初始化状态
**************************************************************/
void initialize(){
int i;
int j;

// average the pheromone value to per edge
// calculate the distance of each edge
for (i = 0; i pheromone[i][i] = INIT_PHEROMONE;
for (j = 0; j city_dis[i][j] = odistance(city_pos[i], city_pos[j], POSITION_DIM);
city_dis[j][i] = city_dis[i][j]; //这里的距离都是相等的
pheromone[i][j] = pheromone[j][i] = INIT_PHEROMONE; //约等于0
}
}
// initialize the tag_old array
init_tag_old();
global_road_dis = 9999999999;
local_road_dis = 9999999999;
}
/**************************************************************
* @function: 初始化tag_old变量
**************************************************************/
void init_tag_old(){
int i;
int j;
for (i = 0; i tag_old[i][0] = 1;
for (j = 1; j tag_old[i][j] = 0;
}
}
}
/**************************************************************
* @function: 找到最好的路径
**************************************************************/
void search_short_road(){
int i;
int times = 0;
while (times // 找当前全局最好的路径
findOneTimeFood();
if (local_road_dis global_road_dis = local_road_dis;
for (i = 0; i global_road_info[i] = local_road_info[i];
}
}//end_if
printf("the %d iteritive: \n", times);
print_cmd();
// update the pheromone matrix
update_pheromone_matrix();
times++;
}//end_while
}
/**************************************************************
* @function: 更新信息素矩阵
**************************************************************/
void update_pheromone_matrix(){
int i;
int j;
for (i = 0; i for (j = 0; j if (1 == is_ij_int_global_road(i, j)){ //在全局最优路径中
pheromone[i][j] = (1-VOLATIE_FACTOR)*pheromone[i][j]
+ VOLATIE_FACTOR / global_road_dis;
}else{ //不在全局最优路径中
pheromone[i][j] = (1-VOLATIE_FACTOR)*pheromone[i][j];
}
}
}
}
/**************************************************************
* @function: 判断ij边在不在global_road中
**************************************************************/
int is_ij_int_global_road(int i, int j){
int k;
int ans = 0;
for (k = 0; k if (i == global_road_info[k]
&& j == global_road_info[k+1]){
ans = 1;
break;
}
}
return ans;
}
/**************************************************************
* @function: 模拟人工蚁群一次找食物的过程 (还是需要修改的)
**************************************************************/
void findOneTimeFood(){
int i;
int j;
int k;
int next_city; //可以表示当前蚂蚁选择的下一个城市下标
double next_city_pro[CITY_NUM]; //存储每一只蚂蚁去下一个城市的概率
int now_road[CITY_NUM+1]; //存储每一只蚂蚁找到的路径
double now_road_dis;
init_tag_old(); //在每次出动的时候,历史信息都将初始化
local_road_dis = 9999999999; //初始化local_road_diss
for (i = 0; i // 计算第i只蚂蚁走的路
now_road[0] = 0;
now_road_dis = 0.0;
for (j = 1; j // 计算第i只蚂蚁去每一个城市的概率
// 并以直方图累加的形式存储在next_city_pro中
next_city_pro[0] = 0.0;
for (k = 1; k double tmp = calculate_Pij(i, now_road[j-1], k);
next_city_pro[k] = next_city_pro[k-1] + tmp;
}
// 产生一个随机数看其落在哪一个区间
double rd = rand_select_value(0.0, 1.0-0.000001); //-0.000001? 确保每个城市都能走到
for (next_city = 1; next_city if (rd break; //k里面存储了第i只蚂蚁的选择下一个城市目标
}
}

tag_old[i][next_city] = 1;
now_road[j] = next_city;
now_road_dis += city_dis[now_road[j-1]][next_city];
}
now_road[CITY_NUM] = 0;
now_road_dis += city_dis[now_road[next_city]][0];
if (now_road_dis local_road_dis = now_road_dis;
for (k = 0; k local_road_info[k] = now_road[k];
}
}
}
}
/**************************************************************
* @function: 计算ant从cityA转移cityB概率
**************************************************************/
double calculate_Pij(int ant, int now_city, int aim_city){
double ans = 0.0;
double sum = 0.0;
int i;
if (0 == tag_old[ant][aim_city]){
for (i = 0; i if (0 == tag_old[ant][i]){
sum += (pow(pheromone[now_city][i], AILFA)
*pow(1/city_dis[now_city][i], BETA));
}
}

double tmp = pow(pheromone[now_city][aim_city], AILFA)*pow(1/city_dis[now_city][aim_city], BETA);
ans = tmp/sum;
}
return ans;
}
/**************************************************************
* @function: 计算两个向量之间的距离
* @notice : 两个向量a与b必须是vector_len长度
**************************************************************/
double odistance(double *a, double *b, int vector_len){
double ans = 0;
int i;
for (i = 0; i ans += (*(a+i)-*(b+i)) * (*(a+i)-*(b+i));
}
ans = sqrt(ans);
return ans;
}
/**************************************************************
* @function: 该函数是在[under, upper]区间中随机
* 选择一个值
**************************************************************/
double rand_select_value(double under, double upper){
if(under>upper) {
printf("\nerror:\t[%d, %d] is invalid region!", under, upper);
exit(1);
}
double lamta = (double)rand()/(RAND_MAX);
return (under+(upper-under)*lamta);
}
/**************************************************************
* @function: 该函数主要是判断两个等长的a向量和b向量是不是一样的
* 如果一样了返回1, 否则返回0
**************************************************************/
int is_same_vector(double* a, double* b, int len){
int ans = 1, i;
for (i = 0; i if (a[i] != b[i]){
ans = 0;
break;
}
}
return ans;
}
/**************************************************************
* @function: 在命令行输出伪次优路径,和路径总长度
**************************************************************/
void print_cmd(){
int i;
for (i = 0; i printf("%d->", global_road_info[i]);
}
printf("%d\ntotal_distance = %.6f\n", global_road_info[CITY_NUM], global_road_dis);
}
/**************************************************************
* @function: 在文件中出伪次优路径,和路径总长度
**************************************************************/
void print_file(double seconds, char* file_path){
FILE *fp = fopen(file_path, "a");
int i;
for (i = 0; i fprintf(fp, "%d->", global_road_info[i]);
}
fprintf(fp, "%d\n总距离为: %.6f\n", global_road_info[CITY_NUM], global_road_dis);
fprintf(fp, "%d次迭代共花: %.2f秒\n", ITERITIVE_NUM, seconds);
fclose(fp);
}


 

//给出DATA30.DAT 测试数据

//(x, y)表示城市的坐标

54 62
58 69
71 71
45 21
25 62
37 84
83 46
41 26
44 35
64 60
22 60
62 32
18 54
68 58
18 40
24 42
91 38
54 67
74 78
83 69
 4 50
82  7
13 40
 2 99
58 35
41 94
87 76
71 44
25 38
 7 64

蚁群算法(ACA)解TSP代码,布布扣,bubuko.com


推荐阅读
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
author-avatar
手机用户2602931635
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有