找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 73|回复: 0

蚁群算法解决TSP问题(c++)

[复制链接]

0

主题

0

回帖

26

积分

管理员

积分
26
发表于 2024-7-16 23:15:23 | 显示全部楼层 |阅读模式
  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<string>
  4. #include<string.h>
  5. #include<cmath>
  6. #include<ctime>
  7. #include<stdlib.h>
  8. using namespace std;
  9. int seed=(int)time(0);//产生随机种子
  10. int CityPos[30][2]= {{87,7},{91,38},{83,46},{71,44},{64,60},{68,58},{83,69},{87,76},{74,78},{71,71},{58,69},{54,62},{51,67},{37,84},{41,94},{2,99},{7,64},{22,60},{25,62},{18,54},{4,50},{13,40},{18,40},{24,42},{25,38},{41,26},{45,21},{44,35},{58,35},{62,32}};
  11. #define CITY_NUM 30//城市数量
  12. #define ANT_NUM 30//蚁群数量
  13. #define TMAC 10000//迭代最大次数
  14. #define ROU 0.5//误差大小
  15. #define ALPHA 1//信息素重要程度的参数
  16. #define BETA 4//启发式因子重要程度的参数
  17. #define Q 100//信息素残留参数
  18. #define maxn 100
  19. #define inf 0x3f3f3f3f
  20. double dis[maxn][maxn];//距离矩阵
  21. double info[maxn][maxn];//信息素矩阵
  22. bool vis[CITY_NUM][CITY_NUM];//标记矩阵
  23. //返回指定范围内的随机整数
  24. int rnd(int low,int upper)
  25. {
  26.     return low+(upper-low)*rand()/(RAND_MAX+1);
  27. }
  28. //返回指定范围内的随机浮点数
  29. double rnd(double low,double upper)
  30. {
  31.     double temp=rand()/((double)RAND_MAX+1.0);
  32.     return low+temp*(upper-low);
  33. }
  34. struct Ant
  35. {
  36.     int path[CITY_NUM];//保存蚂蚁走的路径
  37.     double length;//路径总长度
  38.     bool vis[CITY_NUM];//标记走过的城市
  39.     int cur_cityno;//当前城市
  40.     int moved_cnt;//已走城市数量
  41.     //初始化
  42.     void Init()
  43.     {
  44.         memset(vis,false,sizeof(vis));
  45.         length=0;
  46.         cur_cityno=rnd(0,CITY_NUM);
  47.         path[0]=cur_cityno;
  48.         vis[cur_cityno]=true;
  49.         moved_cnt=1;
  50.     }
  51.     //选择下一个城市
  52.     int Choose()
  53.     {
  54.         int select_city=-1;//所选城市编号
  55.         double sum=0;
  56.         double prob[CITY_NUM];//保存每个城市被选中的概率
  57.         for(int i=0; i<CITY_NUM; i++)
  58.         {
  59.             if(!vis[i])
  60.             {
  61.                 prob[i]=pow(info[cur_cityno][i],ALPHA)*pow(1.0/dis[cur_cityno][i], BETA);
  62.                 sum=sum+prob[i];
  63.             }
  64.             else
  65.             {
  66.                 prob[i]=0;
  67.             }
  68.         }
  69.         //进行轮盘选择
  70.         double temp=0;
  71.         if(sum>0)//总的信息素大于0
  72.         {
  73.             temp=rnd(0.0,sum);
  74.             for(int i=0; i<CITY_NUM; i++)
  75.             {
  76.                 if(!vis[i])
  77.                 {
  78.                     temp=temp-prob[i];
  79.                     if(temp<0.0)
  80.                     {
  81.                         select_city=i;
  82.                         break;
  83.                     }
  84.                 }
  85.             }
  86.         }
  87.         else //信息素太少就随便找个没走过的城市
  88.         {
  89.             for(int i=0; i<CITY_NUM; i++)
  90.             {
  91.                 if(!vis[i])
  92.                 {
  93.                     select_city=i;
  94.                     break;
  95.                 }
  96.             }
  97.         }
  98.         return select_city;
  99.     }
  100.     //蚂蚁的移动
  101.     void Move()
  102.     {
  103.         int nex_cityno=Choose();
  104.         path[moved_cnt]=nex_cityno;
  105.         vis[nex_cityno]=true;
  106.         length=length+dis[cur_cityno][nex_cityno];
  107.         cur_cityno=nex_cityno;
  108.         moved_cnt++;
  109.     }
  110.     //蚂蚁进行一次迭代
  111.     void Search()
  112.     {
  113.         Init();
  114.         while(moved_cnt<CITY_NUM)
  115.         {
  116.             Move();
  117.         }
  118.         //回到原来的城市
  119.         length=length+dis[path[CITY_NUM-1]][path[0]];
  120.     }
  121. };
  122. struct TSP
  123. {
  124.     Ant ants[ANT_NUM];//定义蚁群
  125.     Ant ant_best;//最优路径蚂蚁
  126.     void Init()
  127.     {
  128.         //初始化为最大值
  129.         ant_best.length = inf;
  130.         //计算两两城市间距离
  131.         for (int i = 0; i < CITY_NUM; i++)
  132.         {
  133.             for (int j = 0; j < CITY_NUM; j++)
  134.             {
  135.                 info[i][j]=1.0;
  136.                 double temp1=CityPos[j][0]-CityPos[i][0];
  137.                 double temp2=CityPos[j][1]-CityPos[i][1];
  138.                 dis[i][j] = sqrt(temp1*temp1+temp2*temp2);
  139.             }
  140.         }
  141.     }
  142.     //更新信息素
  143.     void UpdateInfo()
  144.     {
  145.         double temp_info[CITY_NUM][CITY_NUM];
  146.         memset(temp_info,0,sizeof(temp_info));
  147.         int u,v;
  148.         for(int i=0; i<ANT_NUM; i++) //遍历每一只蚂蚁
  149.         {
  150.             for(int j=1; j<CITY_NUM; j++)
  151.             {
  152.                 u=ants[i].path[j-1];
  153.                 v=ants[i].path[j];
  154.                 temp_info[u][v]=temp_info[u][v]+Q/ants[i].length;
  155.                 temp_info[v][u]=temp_info[u][v];
  156.             }
  157.             //最后城市和开始城市之间的信息素
  158.             u=ants[i].path[0];
  159.             temp_info[u][v]=temp_info[u][v]+Q/ants[i].length;
  160.             temp_info[v][u]=temp_info[u][v];
  161.         }
  162.         for(int i=0; i<CITY_NUM; i++)
  163.         {
  164.             for(int j=0; j<CITY_NUM; j++)
  165.             {
  166.                 info[i][j]=info[i][j]*ROU+temp_info[i][j];
  167.             }
  168.         }
  169.     }
  170.     void Search()
  171.     {
  172.         //迭代TMAC次
  173.         for(int i=0; i<TMAC; i++)
  174.         {
  175.             //所有蚂蚁都进行一次遍历
  176.             for(int j=0; j<ANT_NUM; j++)
  177.             {
  178.                 ants[j].Search();
  179.             }
  180.             //保存所有蚂蚁遍历的最佳结果
  181.             for(int j=0; j<ANT_NUM; j++)
  182.             {
  183.                 if(ant_best.length>ants[j].length)
  184.                 {
  185.                     ant_best=ants[j];
  186.                 }
  187.             }
  188.             UpdateInfo();
  189.             printf("第%d次迭代最优路径长度是%lf\n", i,ant_best.length);
  190.             printf("\n");
  191.         }
  192.     }
  193. };
  194. int main()
  195. {
  196.     srand(seed);
  197.     TSP tsp;
  198.     tsp.Init();
  199.     tsp.Search();
  200.     printf("最短路径如下\n");
  201.     for(int i=0;i<CITY_NUM;i++)
  202.     {
  203.         printf("%d",tsp.ant_best.path[i]);
  204.         if(i<CITY_NUM-1)
  205.             printf("->");
  206.         else
  207.             printf("\n");
  208.     }
  209.     return 0;
  210. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2024-12-27 22:10 , Processed in 0.141805 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表