热门标签 | 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


推荐阅读
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • [c++基础]STL
    cppfig15_10.cppincludeincludeusingnamespacestd;templatevoidprintVector(constvector&integer ... [详细]
  • 在 LeetCode 的“有效回文串 II”问题中,给定一个非空字符串 `s`,允许删除最多一个字符。本篇深入解析了如何判断删除一个字符后,字符串是否能成为回文串,并提出了高效的优化算法。通过详细的分析和代码实现,本文提供了多种解决方案,帮助读者更好地理解和应用这一算法。 ... [详细]
  • 本文详细介绍了如何解决DNS服务器配置转发无法解析的问题,包括编辑主配置文件和重启域名服务的具体步骤。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 自定义滚动条美化页面内容
    当页面内容超出显示范围时,为了提升用户体验和页面美观,通常会添加滚动条。如果默认的浏览器滚动条无法满足设计需求,我们可以自定义一个符合要求的滚动条。本文将详细介绍自定义滚动条的实现过程。 ... [详细]
  • 微软推出Windows Terminal Preview v0.10
    微软近期发布了Windows Terminal Preview v0.10,用户可以在微软商店或GitHub上获取这一更新。该版本在2月份发布的v0.9基础上,新增了鼠标输入和复制Pane等功能。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • Spark中使用map或flatMap将DataSet[A]转换为DataSet[B]时Schema变为Binary的问题及解决方案
    本文探讨了在使用Spark的map或flatMap算子将一个数据集转换为另一个数据集时,遇到的Schema变为Binary的问题,并提供了详细的解决方案。 ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 解决Parallels Desktop错误15265的方法
    本文详细介绍了在使用Parallels Desktop时遇到错误15265的多种解决方案,包括检查网络连接、关闭代理服务器和修改主机文件等步骤。 ... [详细]
  • 解决 Windows Server 2016 网络连接问题
    本文详细介绍了如何解决 Windows Server 2016 在使用无线网络 (WLAN) 和有线网络 (以太网) 时遇到的连接问题。包括添加必要的功能和安装正确的驱动程序。 ... [详细]
  • 在使用Eclipse进行调试时,如果遇到未解析的断点(unresolved breakpoint)并显示“未加载符号表,请使用‘file’命令加载目标文件以进行调试”的错误提示,这通常是因为调试器未能正确加载符号表。解决此问题的方法是通过GDB的`file`命令手动加载目标文件,以便调试器能够识别和解析断点。具体操作为在GDB命令行中输入 `(gdb) file `。这一步骤确保了调试环境能够正确访问和解析程序中的符号信息,从而实现有效的调试。 ... [详细]
  • XAMPP 遇到 404 错误:无法找到请求的对象
    在使用 XAMPP 时遇到 404 错误,表示请求的对象未找到。通过详细分析发现,该问题可能由以下原因引起:1. `httpd-vhosts.conf` 文件中的配置路径错误;2. `public` 目录下缺少 `.htaccess` 文件。建议检查并修正这些配置,以确保服务器能够正确识别和访问所需的文件路径。 ... [详细]
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社区 版权所有