找回密码
 立即注册

QQ登录

只需一步,快速开始

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

ACO蚁群优化算法求解TSP旅行商问题C++(2020.10.13)

[复制链接]

0

主题

0

回帖

26

积分

管理员

积分
26
发表于 2024-7-16 23:18:17 | 显示全部楼层 |阅读模式
  1. const int CityCount = 29, AntCount = 29;//城市数量和蚂蚁数量
  2. int besttour[CityCount];//最佳路线
  3. const double α = 1, β = 5,ρ = 0.5, Q = 1;
  4. Graph Map_City;//城市地图,存储城市信息、信息素等
  5. Ant ant[AntCount]//蚁群
  6. const int CityCount = 29, AntCount = 29;//城市数量和蚂蚁数量
  7. int besttour[CityCount];//最佳路线
  8. const double α = 1, β = 5,ρ = 0.5, Q = 1;
  9. Graph Map_City;//城市地图,存储城市信息、信息素等
  10. Ant ant[AntCount]//蚁群
  11. void Ant::Next_City()
  12. {
  13.         int currentcity = tour[tour_citycount - 1];//计算下一步先找到上一步所到的城市
  14.         double temp = 0, sum_probability = 0;
  15.         for (int i = 0; i < CityCount; i++)
  16.         {
  17.                 if (can_visit[i] == true)
  18.                         temp += pow((Map_City.τ[currentcity][i]), α)*pow(1.0 / Map_City.Distance[currentcity][i], β);
  19.         }
  20.         for (int i = 0; i < CityCount; i++)
  21.         {
  22.                 if (can_visit[i] == false)
  23.                         select_probability[i] = 0;//已经到过的城市选择概率为0
  24.                 else
  25.                 {
  26.                         select_probability[i] = pow((Map_City.τ[currentcity][i]), α)*pow(1.0 / Map_City.Distance[currentcity][i], β) / temp;//对于未到过的城市,则计算选择概率
  27.                         sum_probability += select_probability[i];
  28.                 }
  29.         }
  30.         double r = random(0, sum_probability);//取概率区间的随机浮点数
  31.         double p = 0;
  32.         int nextcity = -1;
  33.         for (int j = 0; j < CityCount; j++)
  34.         {
  35.                 if (can_visit[j] == true) p += select_probability[j];
  36.                 if (p >= r)
  37.                 {
  38.                         nextcity = j; break;
  39.                 }
  40.         }
  41.         /*if (nextcity == -1)
  42.         {
  43.                 temp = -1;
  44.                 for (int i = 0; i<CityCount; i++)
  45.                 {
  46.                         if (can_visit[i] == true)
  47.                                 if (temp<pow((Map_City.τ[currentcity][i]), α)*pow(1.0 / Map_City.Distance[currentcity][i], β))
  48.                                 {
  49.                                         temp = pow((Map_City.τ[currentcity][i]), α)*pow(1.0 / Map_City.Distance[currentcity][i], β);
  50.                                         nextcity = i;
  51.                                 }
  52.                 }
  53.         }*/
  54.         Addcity(nextcity);
  55. }
  56. void UpdatePheromones(Graph Map_City,Ant ant[AntCount])//更新信息素的函数
  57. {
  58.         for (int i = 0; i<AntCount; i++)
  59.         {
  60.                 for (int j = 0; j<CityCount - 1; j++)
  61.                 {
  62.                         Map_City.Deltτ[ant[i].tour[j]][ant[i].tour[j + 1]] += Q / ant[i].tour_length;
  63.                         Map_City.Deltτ[ant[i].tour[j + 1]][ant[i].tour[j]] += Q / ant[i].tour_length;
  64.                 }
  65.                 Map_City.Deltτ[ant[i].tour[CityCount - 1]][ant[i].tour[0]] += Q / ant[i].tour_length;
  66.                 Map_City.Deltτ[ant[i].tour[0]][ant[i].tour[CityCount - 1]] += Q / ant[i].tour_length;
  67.         }
  68.         for (int i = 0; i<CityCount; i++)
  69.         {
  70.                 for (int j = 0; j<CityCount; j++)
  71.                 {
  72.                         Map_City.τ[i][j] = (1 - ρ)*Map_City.τ[i][j] + Map_City.Deltτ[i][j];
  73.                         Map_City.Deltτ[i][j] = 0;
  74.                 }
  75.         }
  76. }
  77. // main.cpp
  78. #include <iostream>
  79. #include <fstream>
  80. #include <string>
  81. #include <math.h>
  82. #include <ctime>
  83. using namespace std;
  84. const int CityCount = 29, AntCount = 29;//城市数量和蚂蚁数量
  85. int besttour[CityCount];//最佳路线
  86. const double α = 1, β = 5,ρ = 0.5, Q = 1;
  87. double  random(int low, double uper)//生成某个区间内随机数的函数
  88. {
  89.         return (rand() / (double)RAND_MAX)*(uper - low) + low;
  90. };
  91. int random(int uper)//返回一个从0到最大随机数的任意整数
  92. {
  93.         return (rand() % uper);
  94. };
  95. class City
  96. {
  97. public:
  98.         string name;
  99.         double x, y;//城市的x、y坐标
  100.         void shuchu()
  101.         {
  102.                 std::cout << name << " " << x << " " << y << endl;
  103.         }
  104. };
  105. class Graph//图信息
  106. {
  107. public:
  108.         City city[CityCount];
  109.         double Distance[CityCount][CityCount];//城市间的距离矩阵
  110.         double τ[CityCount][CityCount];//信息素矩阵
  111.         double Deltτ[CityCount][CityCount];//信息素变化量矩阵
  112.         void shuchu()
  113.         {
  114.                 cout << "城市名称 " << "坐标x" << " " << "坐标y" << endl;
  115.                 for (int i = 0; i < CityCount; i++)
  116.                         city[i].shuchu();
  117.                 cout << "距离矩阵: "<< endl;
  118.                 for (int i = 0; i < CityCount; i++)
  119.                 {
  120.                         for (int j = 0; j < CityCount; j++)
  121.                         {
  122.                                 if (j == CityCount - 1)
  123.                                         std::cout << Distance[i][j] << endl;
  124.                                 else
  125.                                         std::cout << Distance[i][j] << "  ";
  126.                         }
  127.                 }
  128.                 cout << "信息素矩阵: " << endl;
  129.                 for (int i = 0; i < CityCount; i++)
  130.                 {
  131.                         for (int j = 0; j < CityCount; j++)
  132.                         {
  133.                                 if (j == CityCount - 1)
  134.                                         std::cout << τ[i][j] << endl;
  135.                                 else
  136.                                         std::cout << τ[i][j] << "  ";
  137.                         }
  138.                 }
  139.                 cout << "信息素增量矩阵: " << endl;
  140.                 for (int i = 0; i < CityCount; i++)
  141.                 {
  142.                         for (int j = 0; j < CityCount; j++)
  143.                         {
  144.                                 if (j == CityCount - 1)
  145.                                         std::cout << Deltτ[i][j] << endl;
  146.                                 else
  147.                                         std::cout << Deltτ[i][j] << "  ";
  148.                         }
  149.                 }
  150.         }
  151.         void Readcoordinatetxt(string txtfilename);//读取城市坐标文件的函数
  152. };
  153. Graph Map_City;//定义全局对象图
  154. void Graph::Readcoordinatetxt(string txtfilename)
  155. {
  156.         ifstream myfile(txtfilename, ios::in);
  157.         double x = 0, y = 0;
  158.         int z = 0;
  159.         if (!myfile.fail())
  160.         {
  161.                 int i = 0;
  162.                 while (!myfile.eof() && (myfile >> z >> x >> y))
  163.                 {
  164.                         city[i].name = to_string(long double(z));//城市名称转化为字符串
  165.                         city[i].x = x; city[i].y = y;
  166.                         i++;
  167.                 }
  168.         }
  169.         else
  170.                 cout << "文件不存在";
  171.         myfile.close();//计算城市距离矩阵
  172.         for (int i = 0; i < CityCount; i++)
  173.                 for (int j = 0; j < CityCount; j++)
  174.                 {
  175.                         Distance[i][j] = sqrt(pow((city[i].x - city[j].x), 2) + pow((city[i].y - city[j].y), 2));//计算城市ij之间的距离
  176.                         τ[i][j] = 1;
  177.                         Deltτ[i][j] = 0;
  178.                 }
  179. }
  180. class Ant
  181. {
  182. public:
  183.         int tour[CityCount + 1];//蚂蚁所构建路径的CityCount+1元数组
  184.         bool can_visit[CityCount];//蚂蚁是否能够访问城市的n元布尔数组
  185.         int tour_citycount;//蚂蚁当前走过城市的数量
  186.         double tour_length, tour_length_shortest;//蚂蚁所走的路径长度tour_length
  187.         double select_probability[CityCount];//蚂蚁对各城市的选择概率数组
  188.         Ant();//蚂蚁的初始化函数
  189.         void Build_Trip();//蚂蚁构造旅行路径的函数
  190.         void Next_City();//蚂蚁选择下一个城市的函数
  191.         void GetFirstCity();//蚂蚁随机到访第一个城市的函数
  192.         void Addcity(int city);//蚂蚁路径上添加城市的函数
  193.         void UpdateTourLength();//更新旅行路径长度的函数
  194.         void Clear();//清空函数
  195. };
  196. Ant ant[AntCount];//蚁群用m元数组ant来表示
  197. Ant::Ant()//蚂蚁的构造函数
  198. {
  199.         tour_length = tour_length_shortest = 0;
  200.         tour_citycount = 0;//起初所旅行过的城市数量为0
  201.         for (int i = 0; i<CityCount; i++)
  202.         {
  203.                 can_visit[i] = true;//每个城市都可以访问
  204.                 select_probability[i] = 0;//选择各个城市的概率为0
  205.         }
  206. }
  207. void Ant::Clear()
  208. {
  209.         tour_length = 0;
  210.         for (int i = 0; i<CityCount; i++)
  211.         {
  212.                 select_probability[i] = 0;
  213.                 can_visit[i] = true;
  214.         }
  215.         tour_citycount = 0;
  216. }
  217. void Ant::Addcity(int city)
  218. {
  219.         //add city to tabu;
  220.         tour[tour_citycount] = city;
  221.         tour_citycount++;
  222.         can_visit[city] = false;
  223. }
  224. void Ant::GetFirstCity()
  225. {
  226.         srand((unsigned)time(NULL) + rand());
  227.         Addcity(random(CityCount));
  228. }
  229. void Ant::Next_City()
  230. {
  231.         int currentcity = tour[tour_citycount - 1];//计算下一步先找到上一步所到的城市
  232.         double temp = 0, sum_probability = 0;
  233.         for (int i = 0; i < CityCount; i++)
  234.         {
  235.                 if (can_visit[i] == true)
  236.                         temp += pow((Map_City.τ[currentcity][i]), α)*pow(1.0 / Map_City.Distance[currentcity][i], β);
  237.         }
  238.         for (int i = 0; i < CityCount; i++)
  239.         {
  240.                 if (can_visit[i] == false)
  241.                         select_probability[i] = 0;//已经到过的城市选择概率为0
  242.                 else
  243.                 {
  244.                         select_probability[i] = pow((Map_City.τ[currentcity][i]), α)*pow(1.0 / Map_City.Distance[currentcity][i], β) / temp;//对于未到过的城市,则计算选择概率
  245.                         sum_probability += select_probability[i];
  246.                 }
  247.         }
  248.         double r = random(0, sum_probability);//取概率区间的随机浮点数
  249.         double p = 0;
  250.         int nextcity = -1;
  251.         for (int j = 0; j < CityCount; j++)
  252.         {
  253.                 if (can_visit[j] == true) p += select_probability[j];
  254.                 if (p >= r)
  255.                 {
  256.                         nextcity = j; break;
  257.                 }
  258.         }
  259.         /*if (nextcity == -1)
  260.         {
  261.                 temp = -1;
  262.                 for (int i = 0; i<CityCount; i++)
  263.                 {
  264.                         if (can_visit[i] == true)
  265.                                 if (temp<pow((Map_City.τ[currentcity][i]), α)*pow(1.0 / Map_City.Distance[currentcity][i], β))
  266.                                 {
  267.                                         temp = pow((Map_City.τ[currentcity][i]), α)*pow(1.0 / Map_City.Distance[currentcity][i], β);
  268.                                         nextcity = i;
  269.                                 }
  270.                 }
  271.         }*/
  272.         Addcity(nextcity);
  273. }
  274. void Ant::Build_Trip()
  275. {
  276.         for (int i = 0; i < CityCount; i++)
  277.         {
  278.                 can_visit[i] = true;
  279.         }
  280.         GetFirstCity();
  281.         while (tour_citycount < CityCount)
  282.         {
  283.                 if(tour_citycount <CityCount) Next_City();//轮盘赌法选择下一个城市
  284.                 else if (tour_citycount == CityCount - 1)
  285.                 {
  286.                         for (int i = 0; i<CityCount; i++)
  287.                                 if (can_visit[i] == true)
  288.                                 {
  289.                                         Addcity(i);
  290.                                         break;
  291.                                 }//如果还剩下一个城市可以访问,那么这个城市就是最后一个城市,添加到蚂蚁旅行的城市上
  292.                 }
  293.         }
  294.         tour[CityCount] = tour[0];//蚂蚁旅行的最后一个城市
  295. }
  296. void Ant::UpdateTourLength()//更新旅行路径长度的函数
  297. {
  298.         for (int i = 0; i<CityCount - 1; i++)
  299.                 tour_length += Map_City.Distance[tour[i]][tour[i + 1]];
  300.         tour_length += Map_City.Distance[tour[CityCount - 1]][tour[0]];
  301. }
  302. void UpdatePheromones(Graph Map_City,Ant ant[AntCount])//更新信息素的函数
  303. {
  304.         for (int i = 0; i<AntCount; i++)
  305.         {
  306.                 for (int j = 0; j<CityCount - 1; j++)
  307.                 {
  308.                         Map_City.Deltτ[ant[i].tour[j]][ant[i].tour[j + 1]] += Q / ant[i].tour_length;
  309.                         Map_City.Deltτ[ant[i].tour[j + 1]][ant[i].tour[j]] += Q / ant[i].tour_length;
  310.                 }
  311.                 Map_City.Deltτ[ant[i].tour[CityCount - 1]][ant[i].tour[0]] += Q / ant[i].tour_length;
  312.                 Map_City.Deltτ[ant[i].tour[0]][ant[i].tour[CityCount - 1]] += Q / ant[i].tour_length;
  313.         }
  314.         for (int i = 0; i<CityCount; i++)
  315.         {
  316.                 for (int j = 0; j<CityCount; j++)
  317.                 {
  318.                         Map_City.τ[i][j] = (1 - ρ)*Map_City.τ[i][j] + Map_City.Deltτ[i][j];
  319.                         Map_City.Deltτ[i][j] = 0;
  320.                 }
  321.         }
  322. }
  323. int main()
  324. {
  325.         int MAX_GEN = 1000;
  326.         double global_tourlength = 10e9,Ljia = DBL_MAX;
  327.         int Tjia[CityCount];//表示蚁群优化算法最终发现的最短路径
  328.         //首先对城市地图进行初始化
  329.         Map_City.Readcoordinatetxt("E:\\下学期课程\\Matlab智能计算\\ACO\\ACO\\bayg29.tsp");
  330.         Map_City.shuchu();
  331.         int temptour[CityCount];
  332.         for (int iteratorcishu = 0; iteratorcishu < MAX_GEN; iteratorcishu++)
  333.         {
  334.                 for (int k = 0; k < AntCount; k++)
  335.                 {
  336.                         ant[k].Build_Trip();
  337.                         ant[k].UpdateTourLength();//计算蚂蚁k所发现路径Tk的长度Lk
  338.                         if (ant[k].tour_length < Ljia)
  339.                         {
  340.                                 for (int h = 0; h < CityCount; h++)
  341.                                         Tjia[h] = ant[k].tour[h];
  342.                                 Ljia = ant[k].tour_length;
  343.                         }
  344.                 }
  345.                 //找到最短的路径长度,放到temp里
  346.                 double temp = ant[0].tour_length;
  347.                 for (int i = 0; i<CityCount; i++) temptour[i] = ant[0].tour[i];
  348.                 for (int i = 0; i<AntCount; i++)
  349.                 {
  350.                         if (temp>ant[i].tour_length)
  351.                         {
  352.                                 temp = ant[i].tour_length;
  353.                                 for (int j = 0; j< CityCount; j++)
  354.                                         temptour[j] = ant[i].tour[j];
  355.                         }
  356.                 }
  357.                 if (temp<global_tourlength)
  358.                 {
  359.                         global_tourlength = temp;
  360.                         for (int j = 0; j< CityCount; j++)
  361.                                 besttour[j] = temptour[j];
  362.                 }
  363.                 std::cout << "第" << iteratorcishu << "次迭代的最短距离:" << global_tourlength << endl;
  364.                 UpdatePheromones(Map_City,ant);
  365.                 for (int i = 0; i < AntCount; i++) ant[i].Clear();
  366.         }
  367.         std::cout << "最短路径为:" << endl;
  368.         for (int i = 0; i < CityCount; i++)
  369.         {
  370.                 if (i == CityCount - 1)std::cout << Map_City.city[besttour[i]].name << endl;
  371.                 else std::cout << Map_City.city[besttour[i]].name << "->";
  372.         }
  373.         std::cout << "最短路径长度为:" << global_tourlength << endl;
  374.         system("Pause");
  375.         return 0;
  376. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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