天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 54|回复: 0

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

[复制链接]
  • TA的每日心情
    开心
    昨天 15:13
  • 签到天数: 153 天

    [LV.7]常住居民III

    3456

    主题

    553

    回帖

    214748万

    积分

    管理员

    中国膜结构网www.mjgou.com

    积分
    2147483647
    QQ
    发表于 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. }
    复制代码

     

     

     

     

    ACO蚁群优化算法求解TSP旅行商问题C++(2020.10.13)
    中国膜结构网打造全中国最好的膜结构综合平台 ,统一协调膜结构设计,膜结构施工,膜材采购,膜材定制,膜结构预算全方位服务。 中国空间膜结构协会合作单位。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池| |网站地图

    GMT+8, 2024-9-8 09:23 , Processed in 0.061710 second(s), 23 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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