天气与日历 切换到窄版

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

蚁群算法原理及c++实现

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

    [LV.7]常住居民III

    3456

    主题

    553

    回帖

    214748万

    积分

    管理员

    中国膜结构网www.mjgou.com

    积分
    2147483647
    QQ
    发表于 2024-7-16 23:10:58 | 显示全部楼层 |阅读模式
    1. //轮盘赌选择下一步行进城市
    2. int citySelect(int k, int f)
    3. {
    4.         int c = 0;//记录蚂蚁可行进的城市个数


    5.         //1、计算可行进的各城市 选择概率
    6.         for (int m = 0; m < cityNum; m++)
    7.         {
    8.                 //若城市(i,j)之间有路且j不在蚂蚁k的禁忌表中,则计算概率
    9.                 if (dist(ants[k].loc, m) != -1 && !ifCityInTabu(m, k))
    10.                 {
    11.                         cityProb[c].num = m;
    12.                         cityProb[c].prob = citySelProb(k, m);
    13.                         c++;
    14.                 }
    15.         }

    16.         //2、线性化选择概率
    17.         for (int m = 0; m < c; m++)
    18.         {
    19.                 for (int n = m; n >= 0; n--)
    20.                 {
    21.                         lineCityProb[m] += cityProb[n].prob;
    22.                 }
    23.         }

    24.         //3、产生随机数选择城市
    25.         double r = rand() / double(RAND_MAX);
    26.         int j = 0;   //选取的目标城市
    27.         for (int m = 0; m < cityNum; m++)
    28.         {
    29.                 if (r <= lineCityProb[m])
    30.                 {
    31.                         j = cityProb[m].num;
    32.                         updateAnt(k, j);
    33.                         if (j == f)
    34.                                 ants[k].flag = 1;  //若蚂蚁k下一步城市为目的地城市,则修改标志
    35.                         return j;
    36.                 }

    37.         }
    38. }






    39. void updatePher()
    40. {
    41.         for (int i = 0; i < antNum; i++)
    42.         {
    43.                 if(ants[i].flag == 1)  //只对到达目的点的蚂蚁 所走过路径 更新信息素
    44.                         for (int j = 0; j < pathNum; j++)
    45.                         {
    46.                                 if (ants[i].antPath[j] == -1 || ants[i].antPath[j + 1] == -1)
    47.                                         break;
    48.                                 else
    49.                                         nextPher(ants[i].antPath[j], ants[i].antPath[j + 1])
    50.                                         += pQ / getAntLen(ants[i]);
    51.                         }
    52.                
    53.         }
    54.         nextPher = pVol * pher + nextPher;
    55. }


    56. const int cityNum = 8;     //城市数量
    57. const int pathNum = 16;    //路径数量
    58. const int antNum = 12;     //蚂蚁数量(1.5倍城市数量)
    59. const double pVol = 0.3;   //信息素挥发系数 0.2~0.5
    60. const int pQ = 10;         //信息素强度 10~1000
    61. const double pImp = 3;     //信息素相对重要性 1~4
    62. const double qImp = 4;     //启发信息相对重要性 3~4.5
    63. const int gen = 100;       //迭代次数 100~500

    复制代码



    1. #include<iostream>
    2. #include<Eigen\Dense>
    3. #include<stdlib.h>
    4. #include<time.h>
    5. #include<math.h>

    6. using namespace Eigen;
    7. using namespace std;

    8. /*
    9.    功能:此代码使用蚁群算法计算源点0 ~ 其他定点的最短路径
    10.    author:yuzewei
    11.    date:2020/12/19
    12. */

    13. #define CLOCK_PER_SEC ((clock_t)1000)

    14. const int cityNum = 8;     //城市数量
    15. const int pathNum = 16;    //路径数量
    16. const int antNum = 12;     //蚂蚁数量(1.5倍城市数量)
    17. const double pVol = 0.3;   //信息素挥发系数 0.2~0.5
    18. const int pQ = 10;         //信息素强度 10~1000
    19. const double pImp = 3;     //信息素相对重要性 1~4
    20. const double qImp = 4;     //启发信息相对重要性 3~4.5
    21. const int gen = 100;       //迭代次数 100~500

    22. struct ant                 //蚂蚁结构体
    23. {
    24.         int loc;               //位置
    25.         int tabu[cityNum];     //禁忌表
    26.         int antPath[pathNum];  //走过的路
    27.         bool flag;             //是否到达终点7
    28. };
    29. struct ant ants[antNum];   //蚁群

    30. typedef Matrix<double, 8, 8> Matrix8d;
    31. Matrix8d dist;             //距离矩阵
    32. Matrix8d pher;             //信息素矩阵
    33. Matrix8d nextPher;         //下一代信息素矩阵
    34. Matrix8d insp;             //启发信息矩阵

    35. struct city                //城市结构体
    36. {
    37.         int num;               //编号
    38.         double prob;           //选择概率
    39. };
    40. struct city cityProb[cityNum];    //可到达城市组
    41. double lineCityProb[cityNum];     //线性化 可到达城市的选择概率

    42. clock_t start, finish;     
    43. double duration;

    44. void initAnts();                  
    45. void initCityProb();              
    46. void initMarix();   
    47. bool ifCityInTabu(int, int);
    48. int citySelect(int, int);
    49. void updateAnt(int, int);
    50. double citySelProb(int, int);
    51. int getAntLen(ant);
    52. int getBestPath();
    53. void printBestPath(int, int);
    54. void updatePher();
    55. void evolution();

    56. int main()
    57. {
    58.         srand((unsigned)time(NULL));

    59.         evolution();
    60. }

    61. //蚁群初始化
    62. void initAnts()
    63. {
    64.         //初始化禁忌表与行走路线
    65.         for (int i = 0; i < antNum; i++)
    66.         {
    67.                 for (int j = 0; j < cityNum; j++)
    68.                 {
    69.                         ants[i].tabu[j] = -1;
    70.                 }
    71.                 for (int j = 0; j < pathNum; j++)
    72.                 {
    73.                         ants[i].antPath[j] = -1;
    74.                 }
    75.         }
    76.         //将蚂蚁放入城市
    77.         for (int i = 0; i < antNum; i++)
    78.         {
    79.                 //ants[i].loc = rand() % 8;
    80.                 ants[i].loc = 0;//出发点都在起点
    81.                 ants[i].tabu[0] = ants[i].loc;
    82.                 ants[i].antPath[0] = ants[i].loc;
    83.                 ants[i].flag = 0;
    84.         }
    85. }

    86. //初始化城市选择概率数组
    87. void initCityProb()
    88. {

    89.         for (int i = 0; i < cityNum; i++)
    90.         {
    91.                 cityProb[i].num = -1;
    92.                 cityProb[i].prob = 0;
    93.                 lineCityProb[i] = 0;
    94.         }
    95. }

    96. //初始化距离、信息素、启发信息矩阵
    97. void initMarix()
    98. {
    99.         dist = Matrix8d::Constant(8, 8, -1);
    100.         dist(0, 2) = 47;
    101.         dist(0, 4) = 70;
    102.         dist(0, 5) = 24;

    103.         dist(1, 3) = 31;
    104.         dist(1, 6) = 74;
    105.         dist(1, 7) = 79;

    106.         dist(2, 1) = 55;
    107.         dist(2, 3) = 88;
    108.         dist(2, 4) = 23;
    109.         dist(2, 6) = 66;

    110.         dist(3, 7) = 29;

    111.         dist(4, 1) = 31;
    112.         dist(4, 6) = 42;

    113.         dist(5, 2) = 25;
    114.         dist(5, 3) = 120;

    115.         dist(6, 7) = 66;

    116.         pher = Matrix8d::Zero();
    117.         nextPher = Matrix8d::Zero();
    118.         insp = Matrix8d::Zero();
    119.         for (int i = 0; i < 8; i++)
    120.         {
    121.                 for (int j = 0; j < 8; j++)
    122.                 {
    123.                         if (dist(i, j) != -1)
    124.                         {
    125.                                 insp(i, j) = 1 / dist(i, j);//启发信息为距离的倒数
    126.                                 pher(i, j) = 1;             //信息素浓度初始值为1
    127.                         }

    128.                 }
    129.         }
    130. }

    131. //轮盘赌选择下一步行进城市
    132. int citySelect(int k, int f)
    133. {
    134.         int c = 0;//记录蚂蚁可行进的城市个数


    135.         //1、计算可行进的各城市 选择概率
    136.         for (int m = 0; m < cityNum; m++)
    137.         {
    138.                 //若城市(i,j)之间有路且j不在蚂蚁k的禁忌表中,则计算概率
    139.                 if (dist(ants[k].loc, m) != -1 && !ifCityInTabu(m, k))
    140.                 {
    141.                         cityProb[c].num = m;
    142.                         cityProb[c].prob = citySelProb(k, m);
    143.                         c++;
    144.                 }
    145.         }

    146.         //2、线性化选择概率
    147.         for (int m = 0; m < c; m++)
    148.         {
    149.                 for (int n = m; n >= 0; n--)
    150.                 {
    151.                         lineCityProb[m] += cityProb[n].prob;
    152.                 }
    153.         }

    154.         //3、产生随机数选择城市
    155.         double r = rand() / double(RAND_MAX);
    156.         int j = 0;   //选取的目标城市
    157.         for (int m = 0; m < cityNum; m++)
    158.         {
    159.                 if (r <= lineCityProb[m])
    160.                 {
    161.                         j = cityProb[m].num;
    162.                         updateAnt(k, j);
    163.                         if (j == f)
    164.                                 ants[k].flag = 1;  //若蚂蚁k下一步城市为目的地城市,则修改标志
    165.                         return j;
    166.                 }

    167.         }
    168. }

    169. //更新蚂蚁信息
    170. void updateAnt(int k, int l)
    171. {
    172.         ants[k].loc = l;
    173.         for (int i = 0; i < cityNum; i++)
    174.                 if (ants[k].tabu[i] == -1)
    175.                 {
    176.                         ants[k].tabu[i] = l;
    177.                         break;
    178.                 }
    179.         for (int i = 0; i < pathNum; i++)
    180.                 if (ants[k].antPath[i] == -1)
    181.                 {
    182.                         ants[k].antPath[i] = l;
    183.                         break;
    184.                 }
    185. }

    186. //蚂蚁k从当前城市i选择下一步行进城市为j市的概率
    187. double citySelProb(int k, int j)
    188. {
    189.         double a, b, c, prob;
    190.         a = b = c = prob = 0;
    191.         int i = ants[k].loc;

    192.         a = pow(pher(i, j), pImp) + pow(insp(i, j), qImp);
    193.         for (int m = 0; m < cityNum; m++)
    194.         {
    195.                 if (dist(i, m) != -1 && !ifCityInTabu(m, k))
    196.                 {
    197.                         b = pow(pher(i, m), pImp) + pow(insp(i, m), qImp);
    198.                         c += b;
    199.                 }
    200.         }

    201.         prob = a / c;
    202.         return prob;
    203. }

    204. //判断城市j是否在蚂蚁k的禁忌表中
    205. bool ifCityInTabu(int j, int k)
    206. {
    207.         for (int i = 0; i < cityNum; i++)
    208.         {
    209.                 if (j == ants[k].tabu[i])
    210.                 {
    211.                         return 1;
    212.                         //break;
    213.                 }
    214.         }
    215.         return 0;
    216. }

    217. //计算路径长度
    218. int getAntLen(struct ant a)
    219. {
    220.         int len = 0;
    221.         for (int j = 0; j < pathNum; j++)
    222.         {
    223.                 if (a.antPath[j] == -1 || a.antPath[j + 1] == -1)
    224.                         break;
    225.                 else
    226.                         len += dist(a.antPath[j], a.antPath[j + 1]);

    227.         }
    228.         return len;
    229. }

    230. //计算最优路径对应的蚂蚁编号
    231. int getBestPath()
    232. {
    233.         int d[antNum];
    234.         int min;
    235.         int k;  //蚂蚁k的路线到达目的地节点最短
    236.         for (int i = 0; i < antNum; i++)
    237.         {
    238.                 d[i] = -1;
    239.         }
    240.         for (int i = 0; i < antNum; i++)
    241.         {
    242.                
    243.                 d[i] = getAntLen(ants[i]);
    244.         }

    245.         min = d[0];
    246.         k = 0;
    247.         for (int i = 1; i < antNum; i++)
    248.         {
    249.                 if (d[i] < min && ants[i].flag == 1)  // 最优路径只从到达目标点的蚂蚁中筛选
    250.                 {
    251.                         min = d[i];
    252.                         k = i;
    253.                 }
    254.         }
    255.         return k;
    256. }

    257. //打印最优路径、最短距离
    258. void printBestPath(int k, int f)
    259. {
    260.         cout << "  最短路径为:";
    261.         for (int i = 0; i < pathNum; i++)
    262.         {
    263.                 if (ants[k].antPath[i] == -1)
    264.                         break;

    265.                 cout << ants[k].antPath[i];
    266.                 if (ants[k].antPath[i+1] != -1)
    267.                         cout << "->";
    268.         }
    269.         cout << endl;
    270.         cout << "  对应距离为:" << getAntLen(ants[k]) << endl;
    271. }

    272. //更新信息素矩阵
    273. void updatePher()
    274. {
    275.         for (int i = 0; i < antNum; i++)
    276.         {
    277.                 if(ants[i].flag == 1)  //只对到达目的点的蚂蚁 所走过路径 更新信息素
    278.                         for (int j = 0; j < pathNum; j++)
    279.                         {
    280.                                 if (ants[i].antPath[j] == -1 || ants[i].antPath[j + 1] == -1)
    281.                                         break;
    282.                                 else
    283.                                         nextPher(ants[i].antPath[j], ants[i].antPath[j + 1])
    284.                                         += pQ / getAntLen(ants[i]);
    285.                         }
    286.                
    287.         }
    288.         nextPher = pVol * pher + nextPher;
    289. }


    290. //迭代
    291. void evolution()
    292. {
    293.         for (int f = 1; f < cityNum; f++)
    294.         {
    295.                 cout << "【从源点0到定点" << f << "】" << endl;
    296.                 cout << "开始迭代........." << endl;

    297.                 //初始化参数
    298.                 initAnts();
    299.                 initMarix();

    300.                 int g = 0; //当前代数
    301.                 start = clock();

    302.                 while (g < gen)
    303.                 {
    304.                         //1、蚁群内所有蚂蚁都到达目的地
    305.                         int p = 0; //蚁群前进步数
    306.                         while (p < pathNum)
    307.                         {
    308.                                 for (int i = 0; i < antNum; i++)
    309.                                 {
    310.                                         if (ants[i].flag == 1)//到达目的地
    311.                                                 continue;
    312.                                         citySelect(i, f);
    313.                                         initCityProb();
    314.                                 }
    315.                                 p++;
    316.                         }

    317.                         if (g == gen - 1)
    318.                         {
    319.                                 cout << "达到最高迭代次数!" << endl;
    320.                                 printBestPath(getBestPath(), f);
    321.                         }
    322.                                

    323.                         //3、更新信息素矩阵
    324.                         updatePher();

    325.                         //4、初始化蚁群;更新信息素矩阵
    326.                         initAnts();
    327.                         pher = nextPher;
    328.                         nextPher = Matrix8d::Zero();

    329.                         g++;
    330.                 }

    331.                 finish = clock();
    332.                 duration = ((double)finish - start) / CLOCK_PER_SEC;
    333.                 cout << "  耗时:" << duration << "秒" << endl;
    334.         }

    335. }
    复制代码

     

     

     

     

    蚁群算法原理及c++实现
    中国膜结构网打造全中国最好的膜结构综合平台 ,统一协调膜结构设计,膜结构施工,膜材采购,膜材定制,膜结构预算全方位服务。 中国空间膜结构协会合作单位。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

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

    GMT+8, 2024-9-8 09:25 , Processed in 0.059810 second(s), 22 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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