天气与日历 切换到窄版

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

c++蚁群算法源码

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

    [LV.7]常住居民III

    3456

    主题

    553

    回帖

    214748万

    积分

    管理员

    中国膜结构网www.mjgou.com

    积分
    2147483647
    QQ
    发表于 2024-7-16 23:16:03 | 显示全部楼层 |阅读模式

    1. #include<iostream>
    2. #include<math.h>
    3. #include<time.h>
    4. using namespace std;

    5. //该程序是以蚁群系统为模型写的蚁群算法程序(强调:非蚂蚁周模型),以三个著名的TSP问题为测试对象
    6. //通过微调参数,都可以获得较好的解

    7. /*
    8. //----------(1)问题一:Oliver 30 城市 TSP 问题 best_length = 423.7406; ------------------------
    9. //该程序最好的结果是423.741,可运行多次获得
    10. //城市节点数目
    11. #define N 30
    12. //城市坐标
    13. double C[N][2]={
    14.         {2,99},{4,50},{7,64},{13,40},{18,54},{18,40},{22,60},{24,42},{25,62},{25,38},
    15.         {37,84},{41,94},{41,26},{44,35},{45,21},{54,67},{54,62},{58,35},{58,69},{62,32},
    16.         {64,60},{68,58},{71,44},{71,71},{74,78},{82,7},{83,46},{83,69},{87,76},{91,38}
    17. };
    18. //----------上面参数是固定的,下面的参数是可变的-----------
    19. //蚂蚁数量
    20. #define M 30
    21. //最大循环次数NcMax
    22. int NcMax = 500;
    23. //信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q0
    24. double alpha = 2, beta = 3, rou = 0.1, alpha1 = 0.1,  qzero = 0.01;
    25. //-----------问题一结束------------------------------------------------------------------------
    26. */

    27. /*
    28. //----------(2)问题二:Elion50 城市 TSP 问题 best_length = 427.96; ----------------------------
    29. //该程序最好的结果是428.468,可运行多次获得
    30. //城市节点数目
    31. #define N 50
    32. //城市坐标
    33. double C[N][2]={
    34.         {5,64}, {5,25}, {5,6}, {7,38}, {8,52}, {10,17},
    35.         {12,42}, {13,13}, {16,57}, {17,33}, {17,63},
    36.         {20,26}, {21,47}, {21,10}, {25,32}, {25,55},
    37.         {27,68}, {27,23}, {30,48}, {30,15}, {31,62},
    38.         {31,32}, {32,22}, {32,39}, {36,16}, {37,69},
    39.         {37,52}, {38,46}, {39,10}, {40,30}, {42,57},
    40.         {42,41}, {43,67}, {45,35}, {46,10}, {48,28},
    41.         {49,49}, {51,21}, {52,33}, {52,41}, {52,64},
    42.         {56,37}, {57,58}, {58,27}, {58,48}, {59,15},
    43.         {61,33}, {62,42}, {62,63}, {63,69}
    44. };
    45. //----------上面参数是固定的,下面的参数是可变的-----------
    46. //蚂蚁数量
    47. #define M 50
    48. //最大循环次数NcMax
    49. int NcMax = 1000;
    50. //信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q0
    51. double alpha = 2, beta = 4, rou = 0.1, alpha1 = 0.1,  qzero = 0.01;
    52. //-----------问题二结束------------------------------------------------------------------------
    53. */

    54. //----------(3)问题三:Elion75 城市 TSP 问题 best_length = 542.31;
    55. //该程序最好的结果是542.309,可运行多次获得
    56. //城市节点数目
    57. #define N 75
    58. //城市坐标
    59. double C[N][2]={
    60. {6,25}, {7,43}, {9,56}, {10,70}, {11,28},
    61. {12,17}, {12,38}, {15,5}, {15,14}, {15,56},
    62. {16,19}, {17,64}, {20,30}, {21,48}, {21,45},
    63. {21,36}, {22,53}, {22,22}, {26,29}, {26,13},
    64. {26,59}, {27,24}, {29,39}, {30,50}, {30,20},
    65. {30,60}, {31,76}, {33,34}, {33,44}, {35,51},
    66. {35,16}, {35,60}, {36,6}, {36,26}, {38,33},
    67. {40,37}, {40,66}, {40,60}, {40,20}, {41,46},
    68. {43,26}, {44,13}, {45,42}, {45,35}, {47,66},
    69. {48,21}, {50,30}, {50,40}, {50,50}, {50,70},
    70. {50,4}, {50,15}, {51,42}, {52,26}, {54,38},
    71. {54,10}, {55,34}, {55,45}, {55,50}, {55,65},
    72. {55,57}, {55,20}, {57,72}, {59,5}, {60,15},
    73. {62,57}, {62,48}, {62,35}, {62,24}, {64,4},
    74. {65,27}, {66,14}, {66,8}, {67,41}, {70,64}
    75. };
    76. //----------上面参数是固定的,下面的参数是可变的-----------
    77. //蚂蚁数量
    78. #define M 75
    79. //最大循环次数NcMax
    80. int NcMax =1000;
    81. //信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q0
    82. double alpha = 2, beta = 5, rou = 0.1, alpha1 = 0.1,  qzero = 0.1;
    83. //-----------问题三结束------------------------------------------------------------------------


    84. //===========================================================================================================
    85. //局部更新时候使用的的常量,它是由最近邻方法得到的一个长度
    86. //什么是最近邻方法?:)就是从源节点出发,每次选择一个距离最短的点来遍历所有的节点得到的路径
    87. //每个节点都可能作为源节点来遍历
    88. double Lnn;
    89. //矩阵表示两两城市之间的距离
    90. double allDistance[N][N];

    91. //计算两个城市之间的距离
    92. double calculateDistance(int i, int j)
    93. {
    94.         return sqrt(pow((C[i][0]-C[j][0]),2.0) + pow((C[i][1]-C[j][1]),2.0));
    95. }

    96. //由矩阵表示两两城市之间的距离
    97. void calculateAllDistance()
    98. {
    99.         for(int i = 0; i < N; i++)
    100.         {
    101.                 for(int j = 0; j < N; j++)
    102.                 {
    103.                         if (i != j)
    104.                         {
    105.                                 allDistance[i][j] = calculateDistance(i, j);
    106.                                 allDistance[j][i] = allDistance[i][j];
    107.                         }
    108.                 }
    109.         }
    110. }

    111. //获得经过n个城市的路径长度
    112. double calculateSumOfDistance(int* tour)
    113. {
    114.         double sum = 0;
    115.         for(int i = 0; i< N ;i++)
    116.         {
    117.                 int row = *(tour + 2 * i);
    118.                 int col = *(tour + 2* i + 1);
    119.                 sum += allDistance[row][col];
    120.         }
    121.         return sum;
    122. }

    123. class ACSAnt;

    124. class AntColonySystem
    125. {
    126. private:       
    127.         double info[N][N], visible[N][N];//节点之间的信息素强度,节点之间的能见度
    128. public:       
    129.         AntColonySystem()
    130.         {
    131.         }
    132.         //计算当前节点到下一节点转移的概率
    133.         double Transition(int i, int j);       
    134.         //局部更新规则
    135.         void UpdateLocalPathRule(int i, int j);       
    136.         //初始化
    137.         void InitParameter(double value);       
    138.         //全局信息素更新
    139.         void UpdateGlobalPathRule(int* bestTour, int globalBestLength);
    140. };

    141. //计算当前节点到下一节点转移的概率
    142. double AntColonySystem::Transition(int i, int j)
    143. {
    144.         if (i != j)
    145.         {
    146.                 return (pow(info[i][j],alpha) * pow(visible[i][j], beta));
    147.         }
    148.         else
    149.         {
    150.                 return 0.0;
    151.         }       
    152. }
    153. //局部更新规则
    154. void AntColonySystem::UpdateLocalPathRule(int i, int j)
    155. {
    156.         info[i][j] = (1.0 - alpha1) * info[i][j] + alpha1 * (1.0 / (N * Lnn));
    157.         info[j][i] = info[i][j];
    158. }
    159. //初始化
    160. void AntColonySystem::InitParameter(double value)
    161. {
    162.         //初始化路径上的信息素强度tao0
    163.         for(int i = 0; i < N; i++)
    164.         {
    165.                 for(int j = 0; j < N; j++)
    166.                 {                               
    167.                         info[i][j] = value;
    168.                         info[j][i] = value;
    169.                         if (i != j)
    170.                         {
    171.                                 visible[i][j] = 1.0 / allDistance[i][j];
    172.                                 visible[j][i] = visible[i][j];
    173.                         }
    174.                 }
    175.         }       
    176. }

    177. //全局信息素更新
    178. void AntColonySystem::UpdateGlobalPathRule(int* bestTour, int globalBestLength)
    179. {
    180.         for(int i = 0; i < N; i++)
    181.         {
    182.                 int row = *(bestTour + 2 * i);
    183.                 int col = *(bestTour + 2* i + 1);
    184.                 info[row][col] = (1.0 - rou) * info[row][col] + rou * (1.0 / globalBestLength);
    185.                 info[col][row] =info[row][col];
    186.         }
    187. }

    188. class ACSAnt
    189. {
    190. private:
    191.         AntColonySystem* antColony;
    192. protected:
    193.         int startCity, cururentCity;//初始城市编号,当前城市编号
    194.         int allowed[N];//禁忌表       
    195.         int Tour[N][2];//当前路径
    196.         int currentTourIndex;//当前路径索引,从0开始,存储蚂蚁经过城市的编号
    197. public:       
    198.         ACSAnt(AntColonySystem* acs, int start)
    199.         {
    200.                 antColony = acs;
    201.                 startCity = start;
    202.         }       
    203.         //开始搜索
    204.         int* Search();
    205.         //选择下一节点
    206.         int Choose();
    207.         //移动到下一节点
    208.         void MoveToNextCity(int nextCity);

    209. };

    210. //开始搜索
    211. int* ACSAnt::Search()
    212. {
    213.         cururentCity = startCity;
    214.         int toCity;
    215.         currentTourIndex = 0;
    216.         for(int i  = 0; i < N; i++)
    217.         {
    218.                 allowed[i] = 1;
    219.         }
    220.         allowed[cururentCity] = 0;
    221.         int endCity;
    222.         int count = 0;
    223.         do
    224.         {
    225.                 count++;
    226.                 endCity = cururentCity;
    227.                 toCity = Choose();               
    228.                 if (toCity >= 0)
    229.                 {                       
    230.                         MoveToNextCity(toCity);
    231.                         antColony->UpdateLocalPathRule(endCity, toCity);
    232.                         cururentCity = toCity;
    233.                 }               
    234.         }while(toCity >= 0);
    235.         MoveToNextCity(startCity);
    236.         antColony->UpdateLocalPathRule(endCity, startCity);

    237.         return *Tour;
    238. }

    239. //选择下一节点
    240. int ACSAnt::Choose()
    241. {
    242.         int nextCity = -1;               
    243.         double q = rand()/(double)RAND_MAX;
    244.         //如果 q <= q0,按先验知识,否则则按概率转移,
    245.         if (q <= qzero)
    246.         {
    247.                 double probability = -1.0;//转移到下一节点的概率
    248.                 for(int i = 0; i < N; i++)
    249.                 {
    250.                         //去掉禁忌表中已走过的节点,从剩下节点中选择最大概率的可行节点
    251.                         if (1 == allowed[i])
    252.                         {
    253.                                 double prob = antColony->Transition(cururentCity, i);
    254.                                 if (prob  > probability)
    255.                                 {
    256.                                         nextCity = i;
    257.                                         probability = prob;
    258.                                 }
    259.                         }
    260.                 }
    261.         }
    262.         else
    263.         {
    264.                 //按概率转移                       
    265.                 double p = rand()/(double)RAND_MAX;//生成一个随机数,用来判断落在哪个区间段
    266.                 double sum = 0.0;                       
    267.                 double probability = 0.0;//概率的区间点,p 落在哪个区间段,则该点是转移的方向
    268.                 //计算概率公式的分母的值
    269.                 for(int i = 0; i < N; i++)
    270.                 {
    271.                         if (1 == allowed[i])
    272.                         {
    273.                                 sum += antColony->Transition(cururentCity, i);
    274.                         }
    275.                 }
    276.                 for(int j = 0; j < N; j++)
    277.                 {
    278.                         if (1 == allowed[j] && sum > 0)
    279.                         {
    280.                                 probability += antColony->Transition(cururentCity, j)/sum;
    281.                                 if (probability >= p || (p > 0.9999 && probability > 0.9999))
    282.                                 {
    283.                                         nextCity = j;
    284.                                         break;
    285.                                 }
    286.                         }
    287.                 }       
    288.         }       
    289.         return nextCity;
    290. }

    291. //移动到下一节点
    292. void ACSAnt::MoveToNextCity(int nextCity)
    293. {
    294.         allowed[nextCity]=0;
    295.         Tour[currentTourIndex][0] = cururentCity;
    296.         Tour[currentTourIndex][1] = nextCity;
    297.         currentTourIndex++;
    298.         cururentCity = nextCity;
    299. }

    300. //------------------------------------------
    301. //选择下一个节点,配合下面的函数来计算的长度
    302. int ChooseNextNode(int currentNode, int visitedNode[])
    303. {
    304.         int nextNode = -1;               
    305.         double shortDistance = 0.0;
    306.         for(int i = 0; i < N; i++)
    307.         {
    308.                 //去掉已走过的节点,从剩下节点中选择距离最近的节点
    309.                 if (1 == visitedNode[i])
    310.                 {                       
    311.                         if (shortDistance == 0.0)
    312.                         {
    313.                                 shortDistance = allDistance[currentNode][i];
    314.                                 nextNode = i;
    315.                         }
    316.                         if(shortDistance < allDistance[currentNode][i])
    317.                         {
    318.                                 nextNode = i;
    319.                         }
    320.                 }
    321.         }
    322.         return nextNode;
    323. }

    324. //给一个节点由最近邻距离方法计算长度
    325. double CalAdjacentDistance(int node)
    326. {
    327.         double sum = 0.0;
    328.         int visitedNode[N];
    329.         for(int j = 0; j < N; j++)
    330.         {
    331.                 visitedNode[j] = 1;
    332.         }
    333.         visitedNode[node] = 0;
    334.         int currentNode = node;
    335.         int nextNode;
    336.         do
    337.         {
    338.                 nextNode = ChooseNextNode(currentNode, visitedNode);
    339.                 if (nextNode >= 0)
    340.                 {
    341.                         sum += allDistance[currentNode][nextNode];
    342.                         currentNode= nextNode;
    343.                         visitedNode[currentNode] = 0;
    344.                 }               
    345.         }while(nextNode >= 0);
    346.         sum += allDistance[currentNode][node];
    347.         return sum;
    348. }

    349. //---------------------------------结束---------------------------------------------

    350. //--------------------------主函数--------------------------------------------------
    351. int main()
    352. {
    353.         time_t timer,timerl;

    354.         time(&timer);
    355.         unsigned long seed = timer;
    356.         seed %= 56000;
    357.         srand((unsigned int)seed);

    358.         //由矩阵表示两两城市之间的距离
    359.         calculateAllDistance();
    360.         //蚁群系统对象
    361.         AntColonySystem* acs = new AntColonySystem();
    362.         ACSAnt* ants[M];
    363.         //蚂蚁均匀分布在城市上
    364.         for(int k = 0; k < M; k++)
    365.         {
    366.                 ants[k] = new ACSAnt(acs, (int)(k%N));
    367.         }
    368.         calculateAllDistance();
    369.         //随机选择一个节点计算由最近邻方法得到的一个长度
    370.         int node = rand() % N;
    371.         Lnn = CalAdjacentDistance(node);
    372.        
    373.         //各条路径上初始化的信息素强度
    374.         double initInfo = 1 / (N * Lnn);
    375.         acs->InitParameter(initInfo);       
    376.        
    377.         //全局最优路径
    378.         int globalTour[N][2];
    379.         //全局最优长度
    380.         double globalBestLength = 0.0;       
    381.         for(int i = 0; i < NcMax; i++)
    382.         {
    383.                 //局部最优路径
    384.                 int localTour[N][2];
    385.                 //局部最优长度
    386.                 double localBestLength = 0.0;
    387.                 //当前路径长度
    388.                 double tourLength;
    389.                 for(int j = 0; j < M; j++)
    390.                 {
    391.                         int* tourPath = ants[j]->Search();
    392.                         tourLength = calculateSumOfDistance(tourPath);                               
    393.                         //局部比较,并记录路径和长度
    394.                         if(tourLength < localBestLength || abs(localBestLength - 0.0) < 0.000001)
    395.                         {                               
    396.                                 for(int m = 0; m< N; m++)
    397.                                 {
    398.                                         int row = *(tourPath + 2 * m);
    399.                                         int col = *(tourPath + 2* m + 1);
    400.                                         localTour[m][0] = row;
    401.                                         localTour[m][1] = col;
    402.                                 }
    403.                                 localBestLength = tourLength;                       
    404.                         }
    405.                 }
    406.                 //全局比较,并记录路径和长度
    407.                 if(localBestLength < globalBestLength || abs(globalBestLength - 0.0) < 0.000001)
    408.                 {                               
    409.                         for(int m = 0; m< N; m++)
    410.                         {
    411.                                 globalTour[m][0] = localTour[m][0];
    412.                                 globalTour[m][1] = localTour[m][1];
    413.                         }
    414.                         globalBestLength = localBestLength;       
    415.                 }
    416.                 acs->UpdateGlobalPathRule(*globalTour, globalBestLength);
    417.                 //输出所有蚂蚁循环一次后的迭代最优路径
    418.                 cout<<"第 "<<i + 1<<" 迭代最优路径:"<<localBestLength<<"."<<endl;
    419.                 for(int m = 0; m< N; m++)
    420.                 {
    421.                         cout<<localTour[m][0]<<".";
    422.                 }
    423.                 cout<<endl;               
    424.         }       
    425.         //输出全局最优路径
    426.         cout<<"全局最优路径长度:"<<globalBestLength<<endl;       
    427.         cout<<"全局最优路径:";
    428.         for(int m = 0; m< N; m++)
    429.         {
    430.                 cout<<globalTour[m][0]<<".";
    431.         }
    432.         cout<<endl;
    433.         time(&timerl);
    434.         int t = timerl - timer;
    435.         return 0;
    436. }
    437. //--------------------------主函数结束--------------------------------------------------
    复制代码

     

     

     

     

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

    本版积分规则

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

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

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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