蚁群算法源代码1
蚁群算法代码
//Basic Ant Colony Algorithm for TSP#include <iostream.h>#include <fstream.h>#include <math.h>#include <time.h>#include <conio.h>#include <stdlib.h>#include <iomanip.h>#define N 31 //city size#define M 31 //ant numberdouble inittao=1;double tao[N][N];double detatao[N][N];double distance[N][N];double yita[N][N];int tabu[M][N];int route[M][N];double solution[M];int BestRoute[N];double BestSolution=10000000000;double alfa,beta,rou,Q;int NcMax;void initparameter(void); // initialize the parameters of basic ACAdouble EvalueSolution(int *a); // evaluate the solution of TSP, and calculate the length of path void InCityXY( double x[], double y[], char *infile ); // input the nodes' coordinates of TSPvoid initparameter(void){alfa=1; beta=5; rou=0.9; Q=100;NcMax=200;}void main(void){int NC=0;initparameter();double x[N];double y[N];InCityXY( x, y, "city31.tsp" );for(int i=0;i<N;i++)for(int j=i+1;j<N;j++){distance[j][i]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); distance[i][j]=distance[j][i];}// calculate the heuristic parametersfor(i=0;i<N;i++)for(int j=0;j<N;j++){tao[i][j]=inittao;if(j!=i)yita[i][j]=100/distance[i][j];}for(int k=0;k<M;k++)for(i=0;i<N;i++)route[k][i]=-1;srand(time(NULL));for(k=0;k<M;k++){route[k][0]=k%N;tabu[k][route[k][0]]=1;}//each ant try to find the optiamal pathdo {int s=1;double partsum;double pper;double drand;//ant choose one whole pathwhile(s<N){for(k=0;k<M;k++){int jrand=rand()%3000;drand=jrand/3001.;partsum=0;pper=0;for(int j=0;j<N;j++){if(tabu[k][j]==0)partsum+=pow(tao[route[k][s-1]][j],alfa)*pow(yita[route[k][s-1]][j],beta); }for(j=0;j<N;j++){if(tabu[k][j]==0)pper+=pow(tao[route[k][s-1]][j],alfa)*pow(yita[route[k][s-1]][j],beta)/partsum; if(pper>drand)break;}tabu[k][j]=1;route[k][s]=j;}s++;}// the pheromone is updatedfor(i=0;i<N;i++)for(int j=0;j<N;j++)detatao[i][j]=0;for(k=0;k<M;k++){solution[k]=EvalueSolution(route[k]);if(solution[k]<BestSolution){BestSolution=solution[k];for(s=0;s<N;s++)BestRoute[s]=route[k][s];}}for(k=0;k<M;k++){for(s=0;s<N-1;s++)detatao[route[k][s]][route[k][s+1]]+=Q/solution[k];detatao[route[k][N-1]][route[k][0]]+=Q/solution[k];}for(i=0;i<N;i++)for(int j=0;j<N;j++){tao[i][j]=rou*tao[i][j]+detatao[i][j];if(tao[i][j]<0.00001)tao[i][j]=0.00001;if(tao[i][j]>20)tao[i][j]=20;}for(k=0;k<M;k++)for(int j=1;j<N;j++){tabu[k][route[k][j]]=0;route[k][j]=-1;}NC++;} while(NC<NcMax);//output the calculating resultsfstream result;result.open("optimal_results.log", ios::app);if(!result){cout<<"can't open the <optimal_results.log> file!\n";exit(0);}result<<"*-------------------------------------------------------------------------*"<<endl; result<<"the initialized parameters of ACA are as follows:"<<endl;result<<"alfa="<<alfa<<", beta="<<beta<<", rou="<<rou<<", Q="<<Q<<endl;result<<"the maximum iteration number of ACA is:"<<NcMax<<endl;result<<"the shortest length of the path is:"<<BestSolution<<endl;result<<"the best route is:"<<endl;for(i=0;i<N;i++)result<<BestRoute[i]<<" ";result<<endl;result<<"*-------------------------------------------------------------------------*"<<endl<<endl; result.close();cout<<"the shortest length of the path is:"<<BestSolution<<endl;}double EvalueSolution(int *a){double dist=0;for(int i=0;i<N-1;i++)dist+=distance[a[i]][a[i+1]];dist+=distance[a[i]][a[0]];return dist;}void InCityXY( double x[], double y[], char *infile ){fstream inxyfile( infile, ios::in | ios::nocreate );if( !inxyfile ){cout<<"can't open the <"<<infile<<"> file!\n";exit(0);}int i=0;while( !inxyfile.eof() ){inxyfile>>x[i]>>y[i];if( ++i >= N ) break;}}31个城市坐标:1304 23123639 13154177 22443712 13993488 15353326 15563238 12294196 10044312 7904386 5703007 19702562 17562788 14912381 16761332 6953715 16783918 21794061 23703780 22123676 25784029 28384263 29313429 19083507 23673394 26433439 32012935 32403140 35502545 23572778 28262370 2975运行后可得到15602的巡游路径改正了n个错误。
蚁群算法源代码1
1.#include<iostream>2.#include<math.h>3.#include<time.h>ing namespace std;5.6.//该程序是以蚁群系统为模型写的蚁群算法程序(强调:非蚂蚁周模型),以三个著名的TSP问题为测试对象7.//通过微调参数,都可以获得较好的解8.9./*10.//----------(1)问题一:Oliver 30 城市 TSP 问题 best_length = 423.7406; ------------------------11.//该程序最好的结果是423.741,可运行多次获得12.//城市节点数目13.#define N 3014.//城市坐标15.double C[N][2]={16. {2,99},{4,50},{7,64},{13,40},{18,54},{18,40},{22,60},{24,42},{25,62},{25,38},17. {37,84},{41,94},{41,26},{44,35},{45,21},{54,67},{54,62},{58,35},{58,69},{62,32},18. {64,60},{68,58},{71,44},{71,71},{74,78},{82,7},{83,46},{83,69},{87,76},{91,38}19.};20.//----------上面参数是固定的,下面的参数是可变的-----------21.//蚂蚁数量22.#define M 3023.//最大循环次数NcMax24.int NcMax = 500;25.//信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q026.double alpha = 2, beta = 3, rou = 0.1, alpha1 = 0.1, qzero = 0.01;27.//-----------问题一结束------------------------------------------------------------------------28.*/29.30./*31.//----------(2)问题二:Elion50 城市 TSP 问题 best_length = 427.96; ----------------------------32.//该程序最好的结果是428.468,可运行多次获得33.//城市节点数目34.#define N 5035.//城市坐标36.double C[N][2]={37. {5,64}, {5,25}, {5,6}, {7,38}, {8,52}, {10,17},38. {12,42}, {13,13}, {16,57}, {17,33}, {17,63},39. {20,26}, {21,47}, {21,10}, {25,32}, {25,55},40. {27,68}, {27,23}, {30,48}, {30,15}, {31,62},41. {31,32}, {32,22}, {32,39}, {36,16}, {37,69},42. {37,52}, {38,46}, {39,10}, {40,30}, {42,57},43. {42,41}, {43,67}, {45,35}, {46,10}, {48,28},44. {49,49}, {51,21}, {52,33}, {52,41}, {52,64},45. {56,37}, {57,58}, {58,27}, {58,48}, {59,15},46. {61,33}, {62,42}, {62,63}, {63,69}47.};48.//----------上面参数是固定的,下面的参数是可变的-----------49.//蚂蚁数量50.#define M 5051.//最大循环次数NcMax52.int NcMax = 1000;53.//信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q054.double alpha = 2, beta = 4, rou = 0.1, alpha1 = 0.1, qzero = 0.01;55.//-----------问题二结束------------------------------------------------------------------------56.*/57.58.//----------(3)问题三:Elion75 城市 TSP 问题 best_length = 542.31;59.//该程序最好的结果是542.309,可运行多次获得60.//城市节点数目61.#define N 7562.//城市坐标63.double C[N][2]={64.{6,25}, {7,43}, {9,56}, {10,70}, {11,28},65.{12,17}, {12,38}, {15,5}, {15,14}, {15,56},66.{16,19}, {17,64}, {20,30}, {21,48}, {21,45},67.{21,36}, {22,53}, {22,22}, {26,29}, {26,13},68.{26,59}, {27,24}, {29,39}, {30,50}, {30,20},69.{30,60}, {31,76}, {33,34}, {33,44}, {35,51},70.{35,16}, {35,60}, {36,6}, {36,26}, {38,33},71.{40,37}, {40,66}, {40,60}, {40,20}, {41,46},72.{43,26}, {44,13}, {45,42}, {45,35}, {47,66},73.{48,21}, {50,30}, {50,40}, {50,50}, {50,70},74.{50,4}, {50,15}, {51,42}, {52,26}, {54,38},75.{54,10}, {55,34}, {55,45}, {55,50}, {55,65},76.{55,57}, {55,20}, {57,72}, {59,5}, {60,15},77.{62,57}, {62,48}, {62,35}, {62,24}, {64,4},78.{65,27}, {66,14}, {66,8}, {67,41}, {70,64}80.//----------上面参数是固定的,下面的参数是可变的-----------81.//蚂蚁数量82.#define M 7583.//最大循环次数NcMax84.int NcMax =1000;85.//信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q086.double alpha = 2, beta = 5, rou = 0.1, alpha1 = 0.1, qzero = 0.1;87.//-----------问题三结束------------------------------------------------------------------------88.89.90.//===========================================================================================================91.//局部更新时候使用的的常量,它是由最近邻方法得到的一个长度92.//什么是最近邻方法?:)就是从源节点出发,每次选择一个距离最短的点来遍历所有的节点得到的路径93.//每个节点都可能作为源节点来遍历94.double Lnn;95.//矩阵表示两两城市之间的距离96.double allDistance[N][N];97.98.//计算两个城市之间的距离99.double calculateDistance(int i, int j)100.{101.return sqrt(pow((C[i][0]-C[j][0]),2.0) + pow((C[i][1]-C[j][1]),2.0)); 102.}103.104.//由矩阵表示两两城市之间的距离105.void calculateAllDistance()106.{107.for(int i = 0; i < N; i++)108. {109.for(int j = 0; j < N; j++)110. {111.if (i != j)112. {113. allDistance[i][j] = calculateDistance(i, j);114. allDistance[j][i] = allDistance[i][j];115. }116. }117. }118.}120.//获得经过n个城市的路径长度121.double calculateSumOfDistance(int* tour)122.{123.double sum = 0;124.for(int i = 0; i< N ;i++)125. {126.int row = *(tour + 2 * i);127.int col = *(tour + 2* i + 1);128. sum += allDistance[row][col];129. }130.return sum;131.}132.133.class ACSAnt;134.135.class AntColonySystem136.{137.private:138.double info[N][N], visible[N][N];//节点之间的信息素强度,节点之间的能见度139.public:140. AntColonySystem()141. {142. }143.//计算当前节点到下一节点转移的概率144.double Transition(int i, int j);145.//局部更新规则146.void UpdateLocalPathRule(int i, int j);147.//初始化148.void InitParameter(double value);149.//全局信息素更新150.void UpdateGlobalPathRule(int* bestTour, int globalBestLength); 151.};152.153.//计算当前节点到下一节点转移的概率154.double AntColonySystem::Transition(int i, int j)155.{156.if (i != j)157. {158.return (pow(info[i][j],alpha) * pow(visible[i][j], beta)); 159. }160.else161. {162.return 0.0;163. }164.}165.//局部更新规则166.void AntColonySystem::UpdateLocalPathRule(int i, int j)167.{168. info[i][j] = (1.0 - alpha1) * info[i][j] + alpha1 * (1.0 / (N * Lnn));169. info[j][i] = info[i][j];170.}171.//初始化172.void AntColonySystem::InitParameter(double value)173.{174.//初始化路径上的信息素强度tao0175.for(int i = 0; i < N; i++)176. {177.for(int j = 0; j < N; j++)178. {179. info[i][j] = value;180. info[j][i] = value;181.if (i != j)182. {183. visible[i][j] = 1.0 / allDistance[i][j];184. visible[j][i] = visible[i][j];185. }186. }187. }188.}189.190.//全局信息素更新191.void AntColonySystem::UpdateGlobalPathRule(int* bestTour, int globalBestLen gth)192.{193.for(int i = 0; i < N; i++)194. {195.int row = *(bestTour + 2 * i);196.int col = *(bestTour + 2* i + 1);197. info[row][col] = (1.0 - rou) * info[row][col] + rou * (1.0 / global BestLength);198. info[col][row] =info[row][col];199. }200.}201.202.class ACSAnt203.{204.private:205. AntColonySystem* antColony;206.protected:207.int startCity, cururentCity;//初始城市编号,当前城市编号208.int allowed[N];//禁忌表209.int Tour[N][2];//当前路径210.int currentTourIndex;//当前路径索引,从0开始,存储蚂蚁经过城市的编号211.public:212. ACSAnt(AntColonySystem* acs, int start)213. {214. antColony = acs;215. startCity = start;216. }217.//开始搜索218.int* Search();219.//选择下一节点220.int Choose();221.//移动到下一节点222.void MoveToNextCity(int nextCity);223.224.};225.226.//开始搜索227.int* ACSAnt::Search()228.{229. cururentCity = startCity;230.int toCity;231. currentTourIndex = 0;232.for(int i = 0; i < N; i++)233. {234. allowed[i] = 1;235. }236. allowed[cururentCity] = 0;237.int endCity;238.int count = 0;239.do240. {241. count++;242. endCity = cururentCity;243. toCity = Choose();244.if (toCity >= 0)245. {246. MoveToNextCity(toCity);247. antColony->UpdateLocalPathRule(endCity, toCity);248. cururentCity = toCity;249. }250. }while(toCity >= 0);251. MoveToNextCity(startCity);252. antColony->UpdateLocalPathRule(endCity, startCity);253.254.return *Tour;255.}256.257.//选择下一节点258.int ACSAnt::Choose()259.{260.int nextCity = -1;261.double q = rand()/(double)RAND_MAX;262.//如果 q <= q0,按先验知识,否则则按概率转移,263.if (q <= qzero)264. {265.double probability = -1.0;//转移到下一节点的概率266.for(int i = 0; i < N; i++)267. {268.//去掉禁忌表中已走过的节点,从剩下节点中选择最大概率的可行节点269.if (1 == allowed[i])270. {271.double prob = antColony->Transition(cururentCity, i); 272.if (prob > probability)273. {274. nextCity = i;275. probability = prob;276. }277. }278. }279. }280.else281. {282.//按概率转移283.double p = rand()/(double)RAND_MAX;//生成一个随机数,用来判断落在哪个区间段284.double sum = 0.0;285.double probability = 0.0;//概率的区间点,p 落在哪个区间段,则该点是转移的方向286.//计算概率公式的分母的值287.for(int i = 0; i < N; i++)288. {289.if (1 == allowed[i])291. sum += antColony->Transition(cururentCity, i);292. }293. }294.for(int j = 0; j < N; j++)295. {296.if (1 == allowed[j] && sum > 0)297. {298. probability += antColony->Transition(cururentCity, j)/sum;299.if (probability >= p || (p > 0.9999 && probability > 0.9999 ))300. {301. nextCity = j;302.break;303. }304. }305. }306. }307.return nextCity;308.}309.310.//移动到下一节点311.void ACSAnt::MoveToNextCity(int nextCity)312.{313. allowed[nextCity]=0;314. Tour[currentTourIndex][0] = cururentCity;315. Tour[currentTourIndex][1] = nextCity;316. currentTourIndex++;317. cururentCity = nextCity;318.}319.320.//------------------------------------------321.//选择下一个节点,配合下面的函数来计算的长度322.int ChooseNextNode(int currentNode, int visitedNode[])323.{324.int nextNode = -1;325.double shortDistance = 0.0;326.for(int i = 0; i < N; i++)327. {328.//去掉已走过的节点,从剩下节点中选择距离最近的节点329.if (1 == visitedNode[i])330. {331.if (shortDistance == 0.0)333. shortDistance = allDistance[currentNode][i]; 334. nextNode = i;335. }336.if(shortDistance < allDistance[currentNode][i]) 337. {338. nextNode = i;339. }340. }341. }342.return nextNode;343.}344.345.//给一个节点由最近邻距离方法计算长度346.double CalAdjacentDistance(int node)347.{348.double sum = 0.0;349.int visitedNode[N];350.for(int j = 0; j < N; j++)351. {352. visitedNode[j] = 1;353. }354. visitedNode[node] = 0;355.int currentNode = node;356.int nextNode;357.do358. {359. nextNode = ChooseNextNode(currentNode, visitedNode); 360.if (nextNode >= 0)361. {362. sum += allDistance[currentNode][nextNode]; 363. currentNode= nextNode;364. visitedNode[currentNode] = 0;365. }366. }while(nextNode >= 0);367. sum += allDistance[currentNode][node];368.return sum;369.}370.371.//---------------------------------结束---------------------------------------------372.373.//--------------------------主函数--------------------------------------------------374.int main()375.{376.time_t timer,timerl;377.378. time(&timer);379. unsigned long seed = timer;380. seed %= 56000;381. srand((unsigned int)seed);382.383.//由矩阵表示两两城市之间的距离384. calculateAllDistance();385.//蚁群系统对象386. AntColonySystem* acs = new AntColonySystem();387. ACSAnt* ants[M];388.//蚂蚁均匀分布在城市上389.for(int k = 0; k < M; k++)390. {391. ants[k] = new ACSAnt(acs, (int)(k%N));392. }393. calculateAllDistance();394.//随机选择一个节点计算由最近邻方法得到的一个长度395.int node = rand() % N;396. Lnn = CalAdjacentDistance(node);397.398.//各条路径上初始化的信息素强度399.double initInfo = 1 / (N * Lnn);400. acs->InitParameter(initInfo);401.402.//全局最优路径403.int globalTour[N][2];404.//全局最优长度405.double globalBestLength = 0.0;406.for(int i = 0; i < NcMax; i++)407. {408.//局部最优路径409.int localTour[N][2];410.//局部最优长度411.double localBestLength = 0.0;412.//当前路径长度413.double tourLength;414.for(int j = 0; j < M; j++)415. {416.int* tourPath = ants[j]->Search();417. tourLength = calculateSumOfDistance(tourPath);418.//局部比较,并记录路径和长度419.if(tourLength < localBestLength || abs(localBestLength - 0.0) <0.000001)420. {421.for(int m = 0; m< N; m++)422. {423.int row = *(tourPath + 2 * m);424.int col = *(tourPath + 2* m + 1);425. localTour[m][0] = row;426. localTour[m][1] = col;427. }428. localBestLength = tourLength;429. }430. }431.//全局比较,并记录路径和长度432.if(localBestLength < globalBestLength || abs(globalBestLength - 0.0 ) < 0.000001)433. {434.for(int m = 0; m< N; m++)435. {436. globalTour[m][0] = localTour[m][0];437. globalTour[m][1] = localTour[m][1];438. }439. globalBestLength = localBestLength;440. }441. acs->UpdateGlobalPathRule(*globalTour, globalBestLength);442.//输出所有蚂蚁循环一次后的迭代最优路径443. cout<<"第 "<<i + 1<<" 迭代最优路径:"<<localBestLength<<"."<<endl; 444.for(int m = 0; m< N; m++)445. {446. cout<<localTour[m][0]<<".";447. }448. cout<<endl;449. }450.//输出全局最优路径451. cout<<"全局最优路径长度:"<<globalBestLength<<endl;452. cout<<"全局最优路径:";453.for(int m = 0; m< N; m++)454. {455. cout<<globalTour[m][0]<<".";456. }457. cout<<endl;458. time(&timerl);459.int t = timerl - timer;460.return 0;461.}462.//--------------------------主函数结束--------------------------------------------------。
蚁群算法代码
蚁群算法代码在⽹上看了⼀些蚁群算法原理,其中最为⼴泛的应⽤还是那个旅⾏家问题(TSP)。
诸如粒⼦群优化算法,蚁群算法都可以求⼀个⽬标函数的最⼩值问题的。
下⾯代码记录下跑的代码。
蚁群算法中最为重要的就是⽬标函数和信息素矩阵的设计。
其他的参数则为信息素重要程度,信息素挥发速度,适应度的重要程度。
import numpy as npfrom scipy import spatialimport pandas as pdimport matplotlib.pyplot as plt'''test Ant Aolony Algorithm'''num_points = 25points_coordinate = np.random.rand(num_points, 2) # generate coordinate of pointsdistance_matrix = spatial.distance.cdist(points_coordinate, points_coordinate, metric='euclidean')# routine 中应该为⼀个列表,其中存放的是遍历过程中的位置编号def cal_total_distance(routine):num_points, = routine.shapereturn sum([distance_matrix[routine[i % num_points], routine[(i + 1) % num_points]] for i in range(num_points)])# %% Do ACAfrom sko.ACA import ACA_TSP'''需要设置的参数包含以下部分:(1): ⽬标函数: ⽤于衡量之前⾛过的的路径的⽬标值(累计路程值), 需要有⼀个参数routine, ⽤于记录遍历的路径位置索引(2): 维度数⽬: 此数字将被⽤于程序进⾏构建遍历路径位置索引(3): 蚁群数⽬: size_pop(4): 最⼤迭代次数: 作为⼀项中值条件(5): 距离(⾪属度/信息素)矩阵: 蚁群算法中⼀般称其为信息素矩阵,需要预先进⾏计算,旨在记录两个路径点之间的距离长度[注意]: 距离矩阵在输⼊之前需要进⾏计算缺点: 速度太慢'''aca = ACA_TSP(func=cal_total_distance, n_dim=num_points,size_pop=500, max_iter=200,distance_matrix=distance_matrix)best_x, best_y = aca.run()# %% Plotfig, ax = plt.subplots(1, 2)best_points_ = np.concatenate([best_x, [best_x[0]]])best_points_coordinate = points_coordinate[best_points_, :]ax[0].plot(best_points_coordinate[:, 0], best_points_coordinate[:, 1], 'o-r')pd.DataFrame(aca.y_best_history).cummin().plot(ax=ax[1])plt.show()。
蚁群算法的Python代码及其效果演示(含注释)
蚁群算法的Python代码及其效果演示(含注释)以下为基本蚁群算法的Python代码(含注释)。
随时可以运行:from turtle import*from random import*from json import loadk=load(open("stats.json"))city_num,ant_num=30,30 #规定城市和蚂蚁总数x_data=k[0] #城市的x坐标之集合y_data=k[1] #城市的y坐标之集合best_length=float("inf")best_path=[]alpha=1beta=7rho=0.5potency_list=[1 for xx in range(city_num**2)]Q=1##城市的index从0开始#下面列表存储城市间距离def get_i_index(n):if n%city_num==0:return n//city_num-1else:return n//city_numdef get_j_index(n):if n%city_num==0:return city_num-1else:return n%city_num-1distance_list=[((x_data[get_i_index(z)]-x_data[get_j_index(z)])**2+(y_data[get_i_index(z)]-y_data[get_j_index(z)])**2)**0.5 for z in range(1,city_num**2+1)]class ant(object):def __init__(self,ant_index):self.ant_index=ant_indexself.cities=list(range(city_num))self.current_length=0self.current_city=randint(0,city_num-1)self.initial_city=self.current_cityself.cities.remove(self.current_city)self.path=[self.current_city]self.length=0#根据城市的index求出两城市间距离def get_distance(self,index_1,index_2):return distance_list[index_1*city_num+index_2]def get_potency(self,index_1,index_2):return potency_list[index_1*city_num+index_2]def get_prob_list(self):res=[self.get_potency(self.current_city,x)**alpha*(1/self.get_distance(self.current_city,x))**bet a for x in self.cities]sum_=sum(res)final_res=[y/sum_ for y in res]return final_res##轮盘赌选择城市def __choose_next_city(self):city_list=self.citiesprob_list=self.get_prob_list()tmp=random()sum_=0for city,prob in zip(city_list,prob_list):sum_+=probif sum_>=tmp:self.length+=self.get_distance(self.current_city,city)self.current_city=cityself.path.append(self.current_city)self.cities.remove(self.current_city)returndef running(self):global best_length,best_pathfor x in range(city_num-1):self.__choose_next_city()self.length+=self.get_distance(self.current_city,self.initial_city)self.path.append(self.initial_city)if self.length<best_length:best_length=self.lengthbest_path=self.pathreturn (self.path,self.length)def go():operation=[]for x in potency_list:x*=(1-rho)for x in range(ant_num):operation.append(ant(x).running())for x in operation:for y in range(city_num-1):potency_list[x[0][y]*city_num+x[0][y+1]]+=Q/x[1]#print(f"potency_list:{potency_list}")#print(f"best_path:{best_path}")#print(f"best_length:{best_length}")for yy in range(1000):go()print(f"best_length:{best_length}")pu()setpos(x_data[best_path[0]],y_data[best_path[0]])pd()for x in range(1,city_num+1):setpos(x_data[best_path[x]],y_data[best_path[x]]) 运行效果:。
蚁群算法matlab代码讲解
蚁群算法matlab代码讲解蚁群算法(Ant Colony Algorithm)是模拟蚁群觅食行为而提出的一种优化算法。
它以蚁群觅食的方式来解决优化问题,比如旅行商问题、图着色问题等。
该算法模拟了蚂蚁在寻找食物时的行为,通过信息素的正反馈和启发式搜索来实现问题的最优解。
在蚁群算法中,首先需要初始化一组蚂蚁和问题的解空间。
每只蚂蚁沿着路径移动,通过信息素和启发式规则来选择下一步的移动方向。
当蚂蚁到达目标位置后,会根据路径的长度来更新信息素。
下面是一个用MATLAB实现蚁群算法的示例代码:```matlab% 参数设置num_ants = 50; % 蚂蚁数量num_iterations = 100; % 迭代次数alpha = 1; % 信息素重要程度因子beta = 5; % 启发式因子rho = 0.1; % 信息素蒸发率Q = 1; % 信息素增加强度因子pheromone = ones(num_cities, num_cities); % 初始化信息素矩阵% 初始化蚂蚁位置和路径ants = zeros(num_ants, num_cities);for i = 1:num_antsants(i, 1) = randi([1, num_cities]);end% 迭代计算for iter = 1:num_iterations% 更新每只蚂蚁的路径for i = 1:num_antsfor j = 2:num_cities% 根据信息素和启发式规则选择下一步移动方向next_city = choose_next_city(pheromone, ants(i, j-1), beta);ants(i, j) = next_city;endend% 计算每只蚂蚁的路径长度path_lengths = zeros(num_ants, 1);for i = 1:num_antspath_lengths(i) = calculate_path_length(ants(i, :), distances);end% 更新信息素矩阵pheromone = (1 - rho) * pheromone;for i = 1:num_antsfor j = 2:num_citiespheromone(ants(i, j-1), ants(i, j)) = pheromone(ants(i, j-1), ants(i, j)) + Q / path_lengths(i); endendend```上述代码中的参数可以根据具体问题进行调整。
蚁群算法python编程实现
蚁群算法python编程实现蚁群算法(Ant Colony Optimization,ACO)是一种群体智能算法,在解决问题时模拟蚂蚁寻找食物的过程,通过蚂蚁在路径上释放信息素的方式引导其他蚂蚁进行探索。
下面是使用Python实现蚁群算法的代码:首先需要导入相关的库:```import numpy as npnp.random.seed(42)```定义一个城市距离矩阵,表示任意两个城市之间的距离:```distance_matrix = np.array([[0, 1, 2, 3, 4],[1, 0, 5, 6, 7],[2, 5, 0, 8, 9],[3, 6, 8, 0, 10],[4, 7, 9, 10, 0]])```定义一个蚂蚁的类,用于描述蚂蚁的位置、经过的城市、路径长度等信息:```class Ant:def __init__(self, num_cities):self.num_cities = num_citiesself.position = np.random.randint(num_cities)self.visited = {self.position}self.path_length = 0def choose_next_city(self, pheromone_matrix, alpha, beta): pheromone_powered =np.power(pheromone_matrix[self.position, :], alpha)distance_powered =np.power(1/distance_matrix[self.position, :], beta)probabilities = (pheromone_powered * distance_powered) probabilities[list(self.visited)] = 0probabilities /= np.sum(probabilities)next_city = np.random.choice(self.num_cities,p=probabilities)self.visited.add(next_city)self.path_length += distance_matrix[self.position,next_city]self.position = next_city```定义一个蚂蚁群体的类,用于描述所有蚂蚁的行为,包括释放信息素、更新信息素等:```class AntColony:def __init__(self, num_ants, num_cities, alpha=1, beta=2, rho=0.5, q0=0.5):self.num_ants = num_antsself.num_cities = num_citiesself.alpha = alphaself.beta = betaself.rho = rhoself.q0 = q0self.pheromone_matrix = np.ones((num_cities,num_cities))def run(self, iterations):best_path_length = np.infbest_path = []for i in range(iterations):ants = [Ant(self.num_cities) for _ inrange(self.num_ants)]for ant in ants:while len(ant.visited) < self.num_cities:ant.choose_next_city(self.pheromone_matrix, self.alpha, self.beta)ant.path_length +=distance_matrix[ant.position, ants[0].position]if ant.path_length < best_path_length:best_path_length = ant.path_lengthbest_path = list(ant.visited)delta_pheromone_matrix =np.zeros((self.num_cities, self.num_cities))for ant in ants:for i in range(self.num_cities):j = list(ant.visited).index(i)if j < self.num_cities - 1:delta_pheromone_matrix[i,list(ant.visited)[j+1]] += 1 / ant.path_lengthelse:delta_pheromone_matrix[i,ants[0].position] += 1 / ant.path_lengthself.pheromone_matrix *= (1 - self.rho)self.pheromone_matrix += delta_pheromone_matrix return best_path_length, best_path```最后,我们可以使用AntColony类来解决一个具体的问题,如下所示:```colony = AntColony(num_ants=10, num_cities=5)colony.run(iterations=1000)```该代码会输出最优路径的长度和经过的城市编号,例如:```(18, [0, 2, 3, 1, 4])```其中,路径的长度为18,依次经过的城市编号为0、2、3、1、4。
蚁群算法 最短路径python
蚁群算法最短路径python蚁群算法是一种模拟蚂蚁寻找食物的算法,可以用于求解最短路径问题。
下面是一个用Python实现的最短路径蚁群算法的示例程序:```pythonimport numpy as np# 定义城市距离矩阵distances = np.array([[0, 2, 3, 5],[2, 0, 4, 7],[3, 4, 0, 4],[5, 7, 4, 0]])# 初始化参数num_cities = 4 # 城市数量num_ants = 5 # 蚂蚁数量pheromone = 0.1 * np.ones((num_cities, num_cities)) # 信息素矩阵alpha = 1 # 信息素重要程度因子beta = 2 # 启发式因子Q = 1 # 常数因子decay = 0.1 # 信息素挥发因子max_iterations = 20 # 最大迭代次数# 主循环for i in range(max_iterations):# 初始化每只蚂蚁的位置和路径长度positions = np.zeros(num_ants, dtype=int)lengths = np.zeros(num_ants)for j in range(num_ants):positions[j] = np.random.randint(num_cities)# 逐个城市路径选择for k in range(num_cities - 1):for j in range(num_ants):# 计算每个城市的行走概率mask = np.ones(num_cities, dtype=bool)mask[positions[j]] = Falsepheromone_temp = np.power(pheromone[positions[j], mask], alpha) * \np.power(1.0 /distances[positions[j], mask], beta)prob = pheromone_temp / np.sum(pheromone_temp)# 轮盘赌选择下一个城市next_city = np.random.choice(num_cities - 1,p=prob) + \(1 if np.sum(mask[:positions[j]]) < positions[j] else 0)positions[j] = next_citylengths[j] += distances[positions[j-1],positions[j]]# 更新信息素delta_pheromone = np.zeros((num_cities, num_cities))for j in range(num_ants):for k in range(num_cities - 1):delta_pheromone[positions[j], positions[j+1]] += Q / lengths[j]pheromone = (1 - decay) * pheromone + delta_pheromone# 输出最短路径best_path_length = np.min(lengths)best_path = positions[np.argmin(lengths)]print(f"Iteration {i}: best path length{best_path_length}, best path {best_path}")```上述程序定义了一个$4\times 4$的城市距离矩阵(即城市之间的直线距离),包含4个城市。
蚁群算法代码
#define MAXX 80
#define MAXY 23
#define MAX_FOOD 10000
#define TARGET_FOOD 200
#define MAX_SMELL 5000
#define SMELL_DROP_RATE 0.05
小小的蚂蚁总是能够找到食物,他们具有什么样的智能呢?设想,如果我们要为蚂蚁设计一个人工智能的程序,那么这个程序要多么复杂呢?首先,你要让蚂蚁能够避开障碍物,就必须根据适当的地形给它编进指令让他们能够巧妙的避开障碍物,其次,要让蚂蚁找到食物,就需要让他们遍历空间上的所有点;再次,如果要让蚂蚁找到最短的路径,那么需要计算所有可能的路径并且比较它们的大小,而且更重要的是,你要小心翼翼的编程,因为程序的错误也许会让你前功尽弃。这是多么不可思议的程序!太复杂了,恐怕没人能够完成这样繁琐冗余的程序。
为什么这么简单的程序会让蚂蚁干这样复杂的事情?答案是:简单规则的涌现。事实上,每只蚂蚁并不是像我们想象的需要知道整个世界的信息,他们其实只关心很小范围内的眼前信息,而且根据这些局部信息利用几条简单的规则进行决策,这样,在蚁群这个集体里,复杂性的行为就会凸现出来。这就是人工生命、复杂性科学解释的规律!
timeuse+=100;
oldsec = t.ti_sec;
}
timeuse+=t.ti_hund-oldhund;
oldhund = t.ti_hund;
if(tu>=60&&!CanFindFood)
{
gotoxy(1,MAXY+1);
printf(“Can not find food, maybe a block world.”);
蚁群算法源程序
void DispSmell(int type)/* input: 0 -- Only display food smell1 -- Only display home smell2 -- Display both food and home smell */{int k,i,j;int fromk,tok;int smelldisp;switch(type){case 0: fromk = 0;tok = 0;break;case 1: fromk = 1;tok = 1;break;case 2: fromk = 0;tok = 1;break;default:fromk = 0;tok = 1;break;}SmellGoneTimer = 0;for(k=fromk;k<=tok;k++)/* SMELL TYPE FOOD and HOME */for(i=1;i<=MAXX;i++)for(j=1;j<=MAXY;j++){if(Smell[k][i][j]){smelldisp = 1+((10*Smell[k][i][j])/(MAX_SMELL*SMELL_DROP_RAT E));if(smelldisp>=30000||smelldisp<0) smelldisp = 30000;gotoxy(i,j);if(i!=food.xxx||j!=food.yyy){if((i==food.xxx&&j==food.yyy)||(i==home.xxx&&j==home.yyy))/* don't over write Food and Home */;else{if(smelldisp>9) putch('#');else putch(smelldisp+'0');}}}} /* of one location */}int AntNextDir(int xxx,int yyy,int ddir){int randnum;int testdir;int CanGoState;int cangof,cangol,cangor;int msf,msl,msr,maxms;int type;CanGoState = CanGo(xxx,yyy,ddir);if(CanGoState==0||CanGoState==2||CanGoState==3||CanGoState==6) cangof = 1;else cangof = 0;if(CanGoState==0||CanGoState==1||CanGoState==3||CanGoState==5) cangol = 1;else cangol = 0;if(CanGoState==0||CanGoState==1||CanGoState==2||CanGoState==4) cangor = 1;else cangor = 0;if(ant[AntNow].food) type = SMELL_TYPE_HOME;else type = SMELL_TYPE_FOOD;msf = GetMaxSmell(type,xxx,yyy,ddir);msl = GetMaxSmell(type,xxx,yyy,TurnLeft(ddir));msr= GetMaxSmell(type,xxx,yyy,TurnRight(ddir));maxms = MaxLocation(msf,msl,msr);/* maxms - 1 - msf is MAX2 - msl is MAX3 - msr is MAX0 - all 3 number is 0 */testdir = NULL;switch(maxms){case 0: /* all is 0, keep testdir = NULL, random select dir */ break;case 1: if(cangof)testdir = ddir;elseif(msl>msr) if(cangol) testdir = TurnLeft(ddir);else if(cangor) testdir = TurnRight(ddir);break;case 2: if(cangol)testdir = TurnLeft(ddir);elseif(msf>msr) if(cangof) testdir = ddir;else if(cangor) testdir = TurnRight(ddir);break;case 3: if(cangor)testdir = TurnRight(ddir);elseif(msf>msl) if(cangof) testdir =ddir;else if(cangol) testdir = TurnLeft(ddir);break;default:break;} /* of maxms */randnum = random(1000);if(randnum<SMELL_DROP_RATE*1000||testdir==NULL)/* 1. if testdir = NULL, means can not find the max smell or the dir to max sm ell can not gothen random select dir2. if ant error, don't follow the smell, random select dir*/{randnum = random(100);switch(CanGoState){case 0: if(randnum<90) testdir = ddir;else if (randnum>=90&&randnum<95) testdir = TurnLeft(ddir);else testdir = TurnRight(ddir);break;case 1: if(randnum<50) testdir = TurnLeft(ddir);else testdir = TurnRight(ddir);break;case 2: if(randnum<90) testdir = ddir;else testdir = TurnRight(ddir);break;case 3: if(randnum<90) testdir = ddir;else testdir = TurnLeft(ddir);break;case 4: testdir = TurnRight(ddir);break;case 5: testdir = TurnLeft(ddir);break;case 6: testdir = ddir;break;case 7: testdir = TurnBack(ddir);break;default:testdir = TurnBack(ddir);} /* of can go state */}return(testdir);}。
蚁群算法c++代码
#include <stdio.h>#include <cmath>#include <iostream>#include <fstream>#include <time.h>#include <cstdlib>using namespace std; //下面的程序使用stdconst int iAntCount=34;//蚂蚁数量,一般取值原则为:城市数量 / 蚂蚁数量 = 1.5左右const int iCityCount=51;//城市数量const int iItCount=2000;// 迭代次数,就是搜索次数const double Q=100; //总的信息素const double alpha=1; //信息素重要程度const double beta=5; //这个数越大,则蚂蚁往信息素大的地方走的概率就越大const double rou=0.5; //环境信息素挥发速度int besttour[iCityCount];// 最佳路径列表double rnd(int low,double uper)// 返回指定范围内的一个随机数{double p=(rand()/(double)RAND_MAX)*((uper)-(low))+(low);return (p);};int rnd(int uper) //返回指定上限范围内的一个随机数{return (rand()%uper);};class GInfo//tsp地图信息,包含了信息素,城市距离,和信息素变化矩阵{public:double m_dDeltTrial[iCityCount][iCityCount]; //临时保存信息素,更新环境信息素的时候使用,每只蚂蚁周游完各个城市后开始计算double m_dTrial[iCityCount][iCityCount]; //当前环境信息素的增加double distance[iCityCount][iCityCount]; //城市间距离};GInfo Map; //环境信息对象全局变量Mapclass ant//定义蚂蚁类{private:int ChooseNextCity();//选择下一个城市double prob[iCityCount]; //未走的城市选择概率,临时变量数组,选择下一个城市的时候,保存各个城市被选中的概率值int m_iCityCount; //记录蚂蚁已经走过的城市数目int AllowedCity[iCityCount]; //城市是否选择1=未走0=已走public:void addcity(int city); //添加城市号int tabu[iCityCount]; //蚂蚁已走的城市号void Clear();//重新初始化void UpdateResult();//更新数据double m_dLength; //单个蚂蚁走过的路径长度double m_dShortest; //蚂蚁走过的最短路径长度void move();//移动到下一个城市ant();//蚂蚁类的构造函数void move2last();};void ant::move2last()//只剩下一个城市没走过时才调用,直接移动到最后一个城市{int i;for(i=0;i<iCityCount;i++)if (AllowedCity[i]==1) //1=未走0=已走{addcity(i);break;}}void ant::Clear()//清空数据,蚂蚁周游完各个城市后,要重新开始周游各个城市时调用。
蚁群算法Delphi源程序
蚁群算法Delphi源程序:{*Ant algorithm for VRP —Ant cycle, Ant density, Ant quantity*}const inf=99999999; eps=1E-8type item=integer;var FN:string; f:System. Text;procedure T_VRPANT_RUN;const maxn=500; ruo=0.7; Q=10;label loop;type item2=real;Arr1=array of array of item;Arr2=array of array of item2;Arr3=array of array of boolean;Arr4=array of array of item;Arr5=array of array of item2;var n,i,j,k,l,ii,jj,count,s,maxcount,tweight,index,model,qq,capa,m,Last,selected,tm,weight:item;tmax,tmin:item2;datatype:byte;W,route,opt,cycle:arrl;t,dt:arr2;ch:arr3;x,y:arr5;Len,tlen,nearest,series,demand,kcount,tkcount:arr4;function PValue(i,j,k:item):item2var 1:item; sum:item2;beginSum:=0;For 1:=2 to n doIf(capa>demand[1])and(ch[1]and(cycle[k,l]=0)and(1< >i)thenSum:=sum+t[i,1]/w[i,l];If(sum>eps)and(cycle[k,j]=0)and(j< >i)thenSun:t[i,j]/ w[i,l]/sumPValue:=sum;end;procedure TwoOpt(p:item);var ahead,i,i1,i2,index,j,j1,j2,last,limit,max,next,s1,s2,t1,t2,maxtemp:item;pt:arr4; beginsetLength(ph,n+1);t1:=1; t2:=1; sl:=1; s2:=1;for I:=1 to p-1 do pt[route[k,i]:=route[k,i+1];pt[route[k,p]:=route[k,l];repeatmaxtemp:=0; i1:=1;for i:=1 to p-2 dobeginif i=1 then limit:=p-1 else limit:=p;i2:=pt[i1]; j1:=pt[i2];for j:=i+2 to limit dobeginj2:=pt[j1]max:=w[i1,i2]+w[j1,j2]-(w[i1,j1]=+w[i2,j2]);if(max>maxtemp)thenbegins1:=i1; s2:=i2; t1=j1; t2=j2; maxtemp:=max;end;j1:=j2;end;i1:=i2;end;if ( maxtemp>0) thenbeginpt[s1]:=t1; next:=s2; last:= t2;repeatahead:=pt[next];pt[next]:=last;last:=next;next:=ahead;until next=t2;end;until(maxtemp=0);index:=1;for i:=1 to p dobeginroute[k,i]:=index; index:=pt[index];end;end;procedure Antmove;label lop, select, check,next;var a,j,k:item;begink:=1; capa:=qq; last:=n-1;for j:=1 to last do series[j]:=j+1;for j:=1 to last do ch[j]:=truefor j:=1 to last do kcount[j]:=0;lop:nearest[k]:=1;for j:=1 to n do cycle[k,j]:=0;select:a:=nearest[k]; j:=1;while j< =last dobeginindex:=0;selected:=random(last)+1;if (capa> =demand[series[selected]])thenbeginindex:=series[selected];if (random<PValue(a,index,k)) then goto check;index:=series[selected];end;j:=j+1;end;if index=0 then goto next;check:cycle[k,nearest[k]]:=index;nearest[k]:=cysle[k,nearest[k]];ch[index]:=false;capa:=capa-demand[index];kcount[k]:=kcountt[k]+1;last:=last-1;for j:=selected to last do series[j]:=series[j+1];if last>=1 then goto select;next:if last>=1 then;begin k:=k+1; capa:=qq; goto lop; end;m:=k;end;beginAssignFile(f,FN); Reset(f);{$I-}Readln(f,n,datatype,qq,maxcount); {$I+}If(IOResult< >0)or(n<4)or(n>maxn)or(maxcount<1)or(datatype<1) or(datatype>2)or(qq<=0) thenbegin ShowMessage(‘数据错误’); System.Close(f); exit; end; SetLength(t,n+1,n+1);SetLength(dt,n+1,n+1);SetLength(w,n+1,n+1);SetLength(opt,n+1,n+1);SetLength(route,n+1,n+1);SetLength(cycle,n+1,n+1);If datatype=1 thenbeginSetLength(x,n+1); SetLength(y,n+1);for i:=1 to n dobegin{$I-}Readln(f,ii,x[i],y[i]); {$I+}If(IOResult< >0)or(ii< >i) thenBegin Show Message(‘数据错误’); System.Close(f); exit; end;end;for i:=1 to n-1 do for j:=i+1 to n dobeginw[i,j]:=trunc(sprt(spr(x[i]-x[j])+spr(y[i]-y[j]))+0.5);w[j,i]:=w[i,j]; t[i,j]:=1; dt[i,j]:=0;t[j,i]:=t[i,j]; dt[j,i]:=dt[i,j];end;for i:=1 to n dobeginw[i,i]:=inf; t[i,i]:=1; dt[i,i]:=0;end;SetLength(x,0); SetLength(y,0);endelsebeginfor i:=1 to n-1 do for j:=i+1 to n dobegin{$I-}Readln(f,ii,jj,w[i,j]); {$I+}If(IOResult< >0)or(ii< >i) or(jj< >j)or(w[i,j]<1)thenbegin Show Message(‘数据错误’); System.Close(f); exit; end;w[j,i]:=w[i,j]; t[i,j]:=1; dt[i,j]:=0;t[j,i]:=t[i,j]; dt[j,i]:=dt[i,j];end;for i:=1 to n dobeginw[i,i]:=inf; t[i,i]:=1; dt[i,i]=0;end;end;SetLength(len,n+1);SetLength(tlen,n+1);SetLength(series,n+1);SetLength(nearest,n+1);SetLength(tkcount,n+1,n+1);SetLength(demand,n+1);SetLength(kcount,n+1);SetLength(ch,n+1);demand[1]:=0;for i:=2 to n dobegin{$I-}Readln(f,ii,demand[i];{$I+}If(IOResult< >0)or(ii< >i)or(demand[i]>qq)or(demand[i]<0)thenbegin Show Message(‘数据错误’); System.Close(f); exit; end;endSystem.Close(f);FN:=Copy(FN,1,Length(FN)-4)+’.OUT’;Show Message(’输出结果存入文件:’+FN);AssignFile(f,FN);Rewrite(f);count:=0;tweight:=inf;index:=1;tm:=inf;randomize;model:=random(3)+1;1oop:AntMove;weight:=0;for k:=1 to m do len[k]:=0;for k:=1 to m dobeginindex:=1;for i:=1 to kcount[k]+1 dobeginroute[k,i]:=index; index:=cycle[k,index];end;TwoOpt(kcount[k]+1);Len[k]:=w[route[k,kcount[k]+1],route[k,1]];for i:=1 to kcount[k] do len[k]:=len[k]+w[route[k,i],route[k,i+1]]; weight:=weight+len[k];end;if m< tm thenbegintm:=m; tweight:=weight;for k:=1 to tm dobegintkcount[k]:=kcount[k];for j:=1 to tkcount[k]+1 do opt[k,j]:=route[k,j];tlen[k]:=len[k];end;end;if m=tm then if tweight>weight thenbegintweight:=weight;for k:=1 to tm dobegintkcount[k]:=kcount[k];for j:=1 to tkcount[k]+1 do opt[k,j]:=route[k,j];tlen[k]:=len[k];end;end;for k:=1 to tm dobegincase model of1: beginfor 1:=1 to kcount[k] dobeginii:=route[k,l];jj=route[k,1+1];dt[ii,jj]:=dt[ii,jj]+q/len[k];end;ii:=route[k,kcount[k]+1]; jj=route[k,1];dt[ii,jj]:=dt[ii,jj]+q/len[k];end;2: beginfor 1:=1 to kcount[k] dobeginii:=route[k,l]; jj:=route[k,1+1];dt[ii,jj]:=dt[ii,jj]+q;end;ii:=route[k,kcount[k]+1]; jj:=route[k,1];dt[ii,jj]:=dt[ii,jj]+q;end;3: beginfor 1:=1 to kcount[k] dobeginii:=route[k,1]; jj:=route[k,l+1]dt[ii,jj]:=dt[ii,jj]+q/w[ii,jj];end;ii:=route[k,kcount[k]+1]; jj:=route[k,1];dt[ii,jj]:=dt[ii,jj]+q/w[ii,jj];endendend;for i:=1 to n do for j:=1 to n dobegint[i,j]:=ruo*t[i,j]+dt[i,j];tmax:=1/(tweight*(1-ruo); tmin=tmax/5;if (t[i,j]>tmax) then t[i,j]:=tmax;if (t[i,j]<tmin) then t[i,j]:=tmin;end;count:=count+1;for i:=1 to n do for j:= 1 to n do dt[i,j]:=0;if count<maxcount then goto loop;for k:=1 to tm dobeginwriteln(f); writeln(f,’第’,k,’条路线:’);writeln(f,’回路总长= ’,then[k]);write(f,’回路路径= ’);for j:= to tkcount[k] +1 do write(f,opt[k,j],’’);writeln(f,’1’); end;writeln(f); writeln(f,’所需车辆数= ’,tm);writeln(f); writeln(f,’车辆总行程= ’,tweight);System.Close(f);end;。
蚁群算法python代码实现
蚁群算法python代码实现蚁群算法是一种基于模拟蚂蚁觅食行为的智能优化算法,适用于求解复杂的优化问题。
本文介绍了蚁群算法的基本原理,并提供了一份Python代码实现。
蚁群算法的基本思想是模拟蚂蚁在寻找食物时的行为,通过蚂蚁之间的信息交流和路径选择来不断优化解的质量。
在蚁群算法中,蚂蚁在搜索过程中会留下信息素,而其他蚂蚁会根据信息素的浓度选择路径,从而不断优化搜索结果。
蚁群算法的核心是信息素更新和路径选择。
信息素更新包括信息素的挥发和信息素的增量,路径选择则通过轮盘赌选择和最大值选择两种方式进行。
下面是蚁群算法的Python实现代码:```import numpy as npclass AntColonyOptimizer:def __init__(self, n_ants, n_iterations, alpha, beta, rho, q, init_pheromone):self.n_ants = n_ants # 蚂蚁数量self.n_iterations = n_iterations # 迭代次数self.alpha = alpha # 信息素重要程度self.beta = beta # 启发因子重要程度self.rho = rho # 信息素挥发速度self.q = q # 信息素增量self.init_pheromone = init_pheromone # 初始信息素浓度 self.distances = None # 距离矩阵self.pheromones = None # 信息素矩阵self.best_path = None # 最佳路径self.best_path_length = np.inf # 最佳路径长度def optimize(self, distances):self.distances = distancesself.pheromones = np.ones_like(self.distances) * self.init_pheromonefor iteration in range(self.n_iterations):paths = self.generate_paths()self.update_pheromones(paths)self.update_best_path(paths)return self.best_path, self.best_path_lengthdef generate_paths(self):paths = []for ant in range(self.n_ants):path = self.generate_path()paths.append(path)return pathsdef generate_path(self):n_cities = self.distances.shape[0]visited_cities = set()path = [np.random.randint(n_cities)]visited_cities.add(path[-1])while len(path) < n_cities:city = self.select_next_city(path, visited_cities)path.append(city)visited_cities.add(city)return pathdef select_next_city(self, path, visited_cities):n_cities = self.distances.shape[0]pheromone_matrix = np.copy(self.pheromones)pheromone_matrix[list(visited_cities), :] = 0pheromone_matrix[:, path[-1]] = 0prob = np.zeros(n_cities)prob[path[-1]] = 0if np.random.rand() < 0.9: # 轮盘赌选择prob = pheromone_matrix[path[-1], :] ** self.alpha * (1.0 / self.distances[path[-1], :]) ** self.betaprob[list(visited_cities)] = 0if np.sum(prob) == 0: # 最大值选择prob = np.ones(n_cities)prob[list(visited_cities)] = 0prob = prob / np.sum(prob)return np.random.choice(range(n_cities), p=prob)def update_pheromones(self, paths):pheromone_delta = np.zeros_like(self.distances)for path in paths:for i in range(len(path) - 1):pheromone_delta[path[i], path[i + 1]] += self.q /self.distances[path[i], path[i + 1]]self.pheromones = (1 - self.rho) * self.pheromones + pheromone_deltadef update_best_path(self, paths):for path in paths:path_length = self.path_length(path)if path_length < self.best_path_length:self.best_path_length = path_lengthself.best_path = pathdef path_length(self, path):return sum([self.distances[path[i], path[i + 1]] for i in range(len(path) - 1)])```需要注意的是,在使用蚁群算法求解优化问题时,需要先将问题转化为图论问题。
蚁群算法代码(求函数最值)
蚁群算法代码(求函数最值)function [F]=F(x1,x2) %⽬标函数F=-(x1.^2+2*x2.^*cos(3*pi*x1)*cos(4*pi*x2)+;Endfunction [maxx,maxy,maxvalue]=antcolony% 蚁群算法求函数最⼤值的程序ant=200; % 蚂蚁数量times=50; % 蚂蚁移动次数rou=; % 信息素挥发系数p0=; % 转移概率常数lower_1=-1; % 设置搜索范围upper_1=1; %lower_2=-1; %upper_2=1; %for i=1 : antX(i,1)=(lower_1+(upper_1-lower_1)*rand);%随机设置蚂蚁的初值位置X(i,2)=(lower_2+(upper_2-lower_2)*rand);tau(i)=F(X(i,1),X(i,2)); %第i只蚂蚁的信息量end %随机初始每只蚂蚁的位置step=; %⽹格划分单位f='-(x.^2+2*y.^*cos(3*pi*x)*cos(4*pi*y)+';[x,y]=meshgrid(lower_1:step:upper_1,lower_2:step:upper_2); z=eval(f); %eval函数,将字符串内的内容执⾏再赋给对象figure(1);mesh(x,y,z); %⽹格图hold on;plot3(X(:,1),X(:,2),tau,'k*') %蚂蚁初始位置hold on;text,,,'蚂蚁的初始分部位置')xlabel('x');ylabel('y');zlabel('f(x,y)');for t=1:times % 第t次移动lamda=1/t; %步长系数,随移动次数增⼤⽽减少[tau_best(t),bestindex]=max(tau); %第t次移动的最优值及其位置for i=1:ant %第i只蚂蚁p(t,i)=(tau(bestindex)-tau(i))/tau(bestindex); %最优值与第i只蚂蚁的值的差⽐% 计算状态转移概率endfor i=1:antif p(t,i)temp1=X(i,1)+(2*rand-1)*lamda; %移动距离temp2=X(i,2)+(2*rand-1)*lamda;else %全局搜索temp1=X(i,1)+(upper_1-lower_1)*;temp2=X(i,2)+(upper_2-lower_2)*;end %%%%%%%%%%%%%%%%%%%%%% 越界处理if temp1temp1=lower_1;endif temp1>upper_1temp1=upper_1;endif temp2temp2=lower_2;endif temp2>upper_2temp2=upper_2;end %%%%%%%%%%%%%%%%%%%%%%%if F(temp1,temp2)>F(X(i,1),X(i,2))% 判断蚂蚁是否移动X(i,1)=temp1;X(i,2)=temp2;endendfor i=1:anttau(i)=(1-rou)*tau(i)+F(X(i,1),X(i,2)); % 更新信息量end endfigure(2);mesh(x,y,z);hold on;x=X(:,1);y=X(:,2);plot3(x,y,eval(f),'k*')hold on;text,,,'蚂蚁的最终分布位置')xlabel('x');ylabel('y'),zlabel('f(x,y)');[max_value,max_index]=max(tau);maxx=X(max_index,1);maxy=X(max_index,2);maxvalue=F(X(max_index,1),X(max_index,2)); end function [F1]=F1(x) %⽬标函数F1=x.^2-2*x+1;End%蚁群算法求解⼀元函数F1=x^2-2*x+1 close clearclcant=10;times=40;rou=;p0=;lb=-2;ub=2;step=;x=lb::ub;for i=1:antX(i)=lb+(ub-lb)*rand;tau(i)=F1(X(i));endfigure(1);plot(x,F1(x));hold onplot(X,tau,'r*');for kk=1:10for t=1:timeslamda=1/t;%转移次数的倒数[tau_best(t),bestindex]=min(tau);for i=1:antp(t,i)=(tau(bestindex)-tau(i))/tau(bestindex);%转移概率(最优-蚂蚁i)/最优%此种概率选择易陷⼊局部最优解endfor i=1:antif p(t,i)temp=X(i)+(2*rand-1)*lamda;%蚂蚁移动elsetemp=X(i)+(ub-lb)*;endif temptemp=lb;endif temp>ubtemp=ub;endif F1(temp)X(i)=temp;endendfor i=1:anttau(i)=(1-rou)*tau(i)+F1(X(i));endendendfigure(2);plot(x,F1(x));hold onx=X(i);y=tau(i);plot(x,y,'g*');x1=X(length(X))y1=tau(length(tau))。
aoc蚁群算法代码
蚁群算法是一种模拟自然界中蚂蚁寻找食物过程的优化算法。
它通过模拟蚂蚁的信息素传递机制,寻找最短路径或最小成本路径。
下面是一个简单的AOC(Ant Colony Optimization)蚁群算法的Python 代码示例:import numpy as npclass AntColony():def __init__(self, distances, n_ants, n_best, n_iterations, decay, alpha=1, beta=1):self.distances = distancesself.n_ants = n_antsself.n_best = n_bestself.n_iterations = n_iterationsself.decay = decayself.alpha = alphaself.beta = betaself.pheromone = np.ones(self.distances.shape) /len(distances)self.shortest_path = Noneself.shortest_path_length = float('inf')self.all_inds = range(len(distances))def update_pheromone(self, path):for i in path:self.pheromone[i] += 1/self.distances[i]self.pheromone *= self.decaydef run(self):for i in range(self.n_iterations):all_trails = [self.gen_random_trail()]all_trails = sorted(all_trails, key=lambda x: x[1], reverse=True)for _ in range(self.n_best):all_trails.remove(min(all_trails))for trail in all_trails:for move in trail[2]:delta = self.pheromone[move]**self.alpha * ((1/self.distances[move])**self.beta)self.pheromone[move] += deltaif not self.shortest_path or move < self.shortest_path:self.shortest_path = moveself.shortest_path_length = trail[1]print("Best solution found: ", self.shortest_path, " with value: ", self.shortest_path_length)print("Pheromone matrix after iteration", i, ":")print(self.pheromone)def gen_random_trail(self):path = []visited = set()start = self.all_inds[0]path.append((start, self.distances[start]))visited.add(start)for i in range(1, len(self.distances)):moves = list(set(self.all_inds) - visited)probabilities = [(self.pheromone[m]**self.alpha * (1/self.distances[m])**self.beta) for m in moves]move = np_choice(moves,probabilities=probabilities)path.append((move, self.distances[move]))visited.add(move)return path在这个代码中,我们首先定义了一个AntColony类,它包含初始化方法__init__和运行方法run。
蚁群算法TSP问题matlab源代码
function[R_best,L_best,L_ave,Shortest_Route,Shortest_Length]=ACATSP(C,NC_max,m,Alpha,Beta ,Rho,Q)%%===================================================== ====================%% ACATSP.m%% Ant Colony Algorithm for Traveling Salesman Problem%% ChengAihua,PLA Information Engineering University,ZhengZhou,China%% Email:aihuacheng@%% All rights reserved%%-------------------------------------------------------------------------%% 主要符号说明%% C n个城市的坐标,n×2的矩阵%% NC_max 最大迭代次数%% m 蚂蚁个数%% Alpha 表征信息素重要程度的参数%% Beta 表征启发式因子重要程度的参数%% Rho 信息素蒸发系数%% Q 信息素增加强度系数%% R_best 各代最佳路线%% L_best 各代最佳路线的长度%%===================================================== ====================%%第一步:变量初始化n=size(C,1);%n表示问题的规模(城市个数)D=zeros(n,n);%D表示完全图的赋权邻接矩阵for i=1:nfor j=1:nif i~=jD(i,j)=((C(i,1)-C(j,1))^2+(C(i,2)-C(j,2))^2)^0.5;elseD(i,j)=eps;endD(j,i)=D(i,j);endendEta=1./D;%Eta为启发因子,这里设为距离的倒数Tau=ones(n,n);%Tau为信息素矩阵Tabu=zeros(m,n);%存储并记录路径的生成NC=1;%迭代计数器R_best=zeros(NC_max,n);%各代最佳路线L_best=inf.*ones(NC_m ax,1);%各代最佳路线的长度L_ave=zeros(NC_max,1);%各代路线的平均长度while NC<=NC_max%停止条件之一:达到最大迭代次数%%第二步:将m只蚂蚁放到n个城市上Randpos=[];for i=1:(ceil(m/n))Randpos=[Randpos,randperm(n)];endTabu(:,1)=(Randpos(1,1:m))';%%第三步:m只蚂蚁按概率函数选择下一座城市,完成各自的周游for j=2:nfor i=1:mvisited=Tabu(i,1:(j-1));%已访问的城市J=zeros(1,(n-j+1));%待访问的城市P=J;%待访问城市的选择概率分布Jc=1;for k=1:nif length(find(visited==k))==0J(Jc)=k;Jc=Jc+1;endend%下面计算待选城市的概率分布for k=1:length(J)P(k)=(Tau(visited(end),J(k))^Alpha)*(Eta(visited(end),J(k))^Beta); endP=P/(sum(P));%按概率原则选取下一个城市Pcum=cumsum(P);Select=find(Pcum>=rand);to_visit=J(Select(1));Tabu(i,j)=to_visit;endendif NC>=2Tabu(1,:)=R_best(NC-1,:);end%%第四步:记录本次迭代最佳路线L=zeros(m,1);for i=1:mR=Tabu(i,:);for j=1:(n-1)L(i)=L(i)+D(R(j),R(j+1));endL(i)=L(i)+D(R(1),R(n));endL_best(NC)=min(L);pos=find(L==L_best(NC));R_best(NC,:)=Tabu(pos(1),:);L_ave(NC)=mean(L);NC=NC+1%%第五步:更新信息素Delta_Tau=zeros(n,n);for i=1:mfor j=1:(n-1)Delta_Tau(Tabu(i,j),Tabu(i,j+1))=Delta_Tau(Tabu(i,j),Tabu(i,j+1))+Q/L(i);endDelta_Tau(Tabu(i,n),Tabu(i,1))=Delta_Tau(Tabu(i,n),Tabu(i,1))+Q/L(i);endTau=(1-Rho).*Tau+Delta_Tau;%%第六步:禁忌表清零Tabu=zeros(m,n);end%%第七步:输出结果Pos=find(L_best==min(L_best));Shortest_Route=R_best(Pos(1),:)Shortest_Length=L_best(Pos(1))subplot(1,2,1)DrawRoute(C,Shortest_Route)subplot(1,2,2)plot(L_best)hold onplot(L_ave)function DrawRoute(C,R)%%===================================================== ====================%% DrawRoute.m%% 画路线图的子函数%%-------------------------------------------------------------------------%% C Coordinate 节点坐标,由一个N×2的矩阵存储%% R Route 路线%%===================================================== ====================N=length(R);scatter(C(:,1),C(:,2));plot([C(R(1),1),C(R(N),1)],[C(R(1),2),C(R(N),2)])hold onfor ii=2:Nplot([C(R(ii-1),1),C(R(ii),1)],[C(R(ii-1),2),C(R(ii),2)]) hold onend设置初始参数如下:m=31;Alpha=1;Beta=5;Rho=0.1;NC_max=200;Q=100; 31城市坐标为:1304 23123639 13154177 22443712 13993488 15353326 15563238 12294196 10044312 7904386 5703007 19702562 17562788 14912381 16761332 6953715 16783918 21794061 23703780 22123676 25784029 28384263 29313429 19083507 23673394 26433439 32012935 32403140 35502545 23572778 28262370 2975运行后得到15602的巡游路径,路线图和收敛曲线如下:。
蚁群算法小程序(CC++语言实现)
蚁群算法⼩程序(CC++语⾔实现)源代码如下:/*ant.c*/#define SPACE 0x20#define ESC 0x1b#define ANT_CHAR_EMPTY '+'#define ANT_CHAR_FOOD 153#define HOME_CHAR 'H'#define FOOD_CHAR 'F'#define FOOD_CHAR2 'f'#define FOOD_HOME_COLOR 12#define BLOCK_CHAR 177#define MAX_ANT 50#define INI_SPEED 3#define MAXX 80#define MAXY 23#define MAX_FOOD 10000#define TARGET_FOOD 200#define MAX_SMELL 5000#define SMELL_DROP_RATE 0.05#define ANT_ERROR_RATE 0.02#define ANT_EYESHOT 3#define SMELL_GONE_SPEED 50#define SMELL_GONE_RATE 0.05#define TRACE_REMEMBER 50#define MAX_BLOCK 100#define NULL 0#define UP 1#define DOWN 2#define LEFT 3#define RIGHT 4#define SMELL_TYPE_FOOD 0#define SMELL_TYPE_HOME 1#include "stdio.h"#include "conio.h"#include "dos.h"#include "stdlib.h"#include "dos.h"#include "process.h"#include "ctype.h"#include "math.h"void WorldInitial(void);void BlockInitial(void);void CreatBlock(void);void SaveBlock(void);void LoadBlock(void);void HomeFoodInitial(void);void AntInitial(void);void WorldChange(void);void AntMove(void);void AntOneStep(void);void DealKey(char key);void ClearSmellDisp(void);void DispSmell(int type);int AntNextDir(int xxx,int yyy,int ddir);int GetMaxSmell(int type,int xxx,int yyy,int ddir);int IsTrace(int xxx,int yyy);int MaxLocation(int num1,int num2,int num3);int CanGo(int xxx,int yyy,int ddir);int JudgeCanGo(int xxx,int yyy);int TurnLeft(int ddir);int TurnRight(int ddir);int TurnBack(int ddir);int MainTimer(void);char WaitForKey(int secnum);void DispPlayTime(void);int TimeUse(void);void HideCur(void);void ResetCur(void);/* --------------- */struct HomeStruct{int xxx,yyy;int amount;int TargetFood;}home;struct FoodStruct{int xxx,yyy;int amount;}food;struct AntStruct{int xxx,yyy;int dir;int speed;int SpeedTimer;int food;int SmellAmount[2];int tracex[TRACE_REMEMBER];int tracey[TRACE_REMEMBER];int TracePtr;int IQ;}ant[MAX_ANT];int AntNow;int timer10ms;struct time starttime,endtime;int Smell[2][MAXX+1][MAXY+1];int block[MAXX+1][MAXY+1];int SmellGoneTimer;int SmellDispFlag;int CanFindFood;int HardtoFindPath;/* ----- Main -------- */void main(void){char KeyPress;int tu;clrscr();HideCur();WorldInitial();do{timer10ms = MainTimer();if(timer10ms) AntMove();if(timer10ms) WorldChange();tu = TimeUse();if(tu>=60&&!CanFindFood){gotoxy(1,MAXY+1);printf("Can not find food, maybe a block world."); WaitForKey(10);WorldInitial();}if(tu>=180&&home.amount<100&&!HardtoFindPath){gotoxy(1,MAXY+1);printf("God! it is so difficult to find a path.");if(WaitForKey(10)==0x0d) WorldInitial();else{HardtoFindPath = 1;gotoxy(1,MAXY+1);printf(" ");}}if(home.amount>=home.TargetFood){gettime(&endtime);KeyPress = WaitForKey(60);DispPlayTime();WaitForKey(10);WorldInitial();}else if(kbhit()){KeyPress = getch();DealKey(KeyPress);}else KeyPress = NULL;}while(KeyPress!=ESC);gettime(&endtime);DispPlayTime();WaitForKey(10);clrscr();ResetCur();}/* ------ general sub process ----------- */int MainTimer(void)/* output: how much 10ms have pass from last time call this process */{static int oldhund,oldsec;struct time t;int timeuse;gettime(&t);timeuse = 0;if(t.ti_hund!=oldhund){if(t.ti_sec!=oldsec){timeuse+=100;oldsec = t.ti_sec;}timeuse+=t.ti_hund-oldhund;oldhund = t.ti_hund;}else timeuse = 0;return (timeuse);}char WaitForKey(int secnum)/* funtion: if have key in, exit immediately, else wait 'secnum' senconds then exit input: secnum -- wait this senconds, must < 3600 (1 hour)output: key char, if no key in(exit when timeout), return NULL */{int secin,secnow;int minin,minnow;int hourin,hournow;int secuse;struct time t;gettime(&t);secin = t.ti_sec;minin = t.ti_min;hourin = t.ti_hour;do{if(kbhit()) return(getch());gettime(&t);secnow = t.ti_sec;minnow = t.ti_min;hournow = t.ti_hour;if(hournow!=hourin) minnow+=60;if(minnow>minin) secuse = (minnow-1-minin) + (secnow+60-secin); else secuse = secnow - secin;/* counting error check */if(secuse<0){gotoxy(1,MAXY+1);printf("Time conuting error, any keyto exit...");getch();exit(3);}}while(secuse<=secnum);return (NULL);}void DispPlayTime(void){int ph,pm,ps;ph = endtime.ti_hour - starttime.ti_hour;pm = endtime.ti_min - starttime.ti_min;ps = endtime.ti_sec - starttime.ti_sec;if(ph<0) ph+=24;if(pm<0) { ph--; pm+=60; }if(ps<0) { pm--; ps+=60; }gotoxy(1,MAXY+1);printf("Time use: %d hour- %d min- %d sec ",ph,pm,ps);}int TimeUse(void){int ph,pm,ps;gettime(&endtime);ph = endtime.ti_hour - starttime.ti_hour;pm = endtime.ti_min - starttime.ti_min;ps = endtime.ti_sec - starttime.ti_sec;if(ph<0) ph+=24;if(pm<0) { ph--; pm+=60; }if(ps<0) { pm--; ps+=60; }return(ps+(60*(pm+60*ph)));}void HideCur(void){union REGS regs0;regs0.h.ah=1;regs0.h.ch=0x30;regs0.h.cl=0x31;int86(0x10,®s0,®s0);}void ResetCur(void){union REGS regs0;regs0.h.ah=1;regs0.h.ch=0x06;regs0.h.cl=0x07;int86(0x10,®s0,®s0);}/* ------------ main ANT programe ------------- */void WorldInitial(void){int k,i,j;randomize();clrscr();HomeFoodInitial();for(AntNow=0;AntNow<MAX_ANT;AntNow++){AntInitial();} /* of for AntNow */;BlockInitial();for(k=0;k<=1;k++)/* SMELL TYPE FOOD and HOME */for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++)Smell[k][i][j] = 0;SmellGoneTimer = 0;gettime(&starttime);SmellDispFlag = 0;CanFindFood = 0;HardtoFindPath = 0;}void BlockInitial(void){int i,j;int bn;for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++)block[i][j] = 0;bn = 1+ MAX_BLOCK/2 + random(MAX_BLOCK/2);for(i=0;i<=bn;i++) CreatBlock();}void CreatBlock(void){int x1,y1,x2,y2;int dx,dy;int i,j;x1 = random(MAXX)+1;y1 = random(MAXY)+1;dx = random(MAXX/10)+1;dy = random(MAXY/10)+1;x2 = x1+dx;y2 = y1+dy;if(x2>MAXX) x2 = MAXX;if(y2>MAXY) y2 = MAXY;if(food.xxx>=x1&&food.xxx<=x2&&food.yyy>=y1&&food.yyy<=y2) return;if(home.xxx>=x1&&home.xxx<=x2&&home.yyy>=y1&&home.yyy<=y2) return; for(i=x1;i<=x2;i++)for(j=y1;j<=y2;j++){block[i][j] = 1;gotoxy(i,j);putch(BLOCK_CHAR);}}void SaveBlock(void){FILE *fp_block;char FileNameBlock[20];int i,j;gotoxy(1,MAXY+1);printf(" ");gotoxy(1,MAXY+1);printf("Save to file...",FileNameBlock);gets(FileNameBlock);if(FileNameBlock[0]==0) strcpy(FileNameBlock,"Ant.ant");else strcat(FileNameBlock,".ant");if ((fp_block = fopen(FileNameBlock, "wb")) == NULL){ gotoxy(1,MAXY+1);printf("Creat file %s fail...",FileNameBlock);getch();exit(2);}gotoxy(1,MAXY+1);printf(" ");fputc(home.xxx,fp_block);fputc(home.yyy,fp_block);fputc(food.xxx,fp_block);fputc(food.yyy,fp_block);for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++)fputc(block[i][j],fp_block);fclose(fp_block);}void LoadBlock(void){FILE *fp_block;char FileNameBlock[20];int i,j,k;gotoxy(1,MAXY+1);printf(" ");gotoxy(1,MAXY+1);printf("Load file...",FileNameBlock);gets(FileNameBlock);if(FileNameBlock[0]==0) strcpy(FileNameBlock,"Ant.ant");else strcat(FileNameBlock,".ant");if ((fp_block = fopen(FileNameBlock, "rb")) == NULL){ gotoxy(1,MAXY+1);printf("Open file %s fail...",FileNameBlock);getch();exit(2);}clrscr();home.xxx = fgetc(fp_block);home.yyy = fgetc(fp_block);food.xxx = fgetc(fp_block);food.yyy = fgetc(fp_block);gotoxy(home.xxx,home.yyy); putch(HOME_CHAR);gotoxy(food.xxx,food.yyy); putch(FOOD_CHAR);food.amount = random(MAX_FOOD/3)+2*MAX_FOOD/3+1;/* food.amount = MAX_FOOD; */home.amount = 0;home.TargetFood = (food.amount<TARGET_FOOD)?food.amount:TARGET_FOOD; for(AntNow=0;AntNow<MAX_ANT;AntNow++){AntInitial();} /* of for AntNow */;for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++){block[i][j] = fgetc(fp_block);if(block[i][j]){gotoxy(i,j);putch(BLOCK_CHAR);}}for(k=0;k<=1;k++)/* SMELL TYPE FOOD and HOME */for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++)Smell[k][i][j] = 0;SmellGoneTimer = 0;gettime(&starttime);SmellDispFlag = 0;CanFindFood = 0;HardtoFindPath = 0;fclose(fp_block);}void HomeFoodInitial(void){int randnum;int homeplace;/* 1 -- home at left-up, food at right-down2 -- home at left-down, food at right-up3 -- home at right-up, food at left-down4 -- home at right-down, food at left-up */randnum = random(100);if(randnum<25) homeplace = 1;else if (randnum>=25&&randnum<50) homeplace = 2;else if (randnum>=50&&randnum<75) homeplace = 3;else homeplace = 4;switch(homeplace){case 1: home.xxx = random(MAXX/3)+1;home.yyy = random(MAXY/3)+1;food.xxx = random(MAXX/3)+2*MAXX/3+1;food.yyy = random(MAXY/3)+2*MAXY/3+1;break;case 2: home.xxx = random(MAXX/3)+1;home.yyy = random(MAXY/3)+2*MAXY/3+1;food.xxx = random(MAXX/3)+2*MAXX/3+1;food.yyy = random(MAXY/3)+1;break;case 3: home.xxx = random(MAXX/3)+2*MAXX/3+1;home.yyy = random(MAXY/3)+1;food.xxx = random(MAXX/3)+1;food.yyy = random(MAXY/3)+2*MAXY/3+1;break;case 4: home.xxx = random(MAXX/3)+2*MAXX/3+1;home.yyy = random(MAXY/3)+2*MAXY/3+1;food.xxx = random(MAXX/3)+1;food.yyy = random(MAXY/3)+1;break;}food.amount = random(MAX_FOOD/3)+2*MAX_FOOD/3+1;/* food.amount = MAX_FOOD; */home.amount = 0;home.TargetFood = (food.amount<TARGET_FOOD)?food.amount:TARGET_FOOD; /* data correctness check */if(home.xxx<=0||home.xxx>MAXX||home.yyy<=0||home.yyy>MAXY||food.xxx<=0||food.xxx>MAXX||food.yyy<=0||food.yyy>MAXY||food.amount<=0){gotoxy(1,MAXY+1);printf("World initial fail, any key to exit...");getch();exit(2);}gotoxy(home.xxx,home.yyy); putch(HOME_CHAR);gotoxy(food.xxx,food.yyy); putch(FOOD_CHAR);}void AntInitial(void)/* initial ant[AntNow] */{int randnum;int i;ant[AntNow].xxx = home.xxx;ant[AntNow].yyy = home.yyy;randnum = random(100);if(randnum<25) ant[AntNow].dir = UP;else if (randnum>=25&&randnum<50) ant[AntNow].dir = DOWN;else if (randnum>=50&&randnum<75) ant[AntNow].dir = LEFT;else ant[AntNow].dir = RIGHT;ant[AntNow].speed = 2*(random(INI_SPEED/2)+1);ant[AntNow].SpeedTimer = 0;ant[AntNow].food = 0;ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = 0;ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = MAX_SMELL;ant[AntNow].IQ = 1;for(i=0;i<TRACE_REMEMBER;i++){ant[AntNow].tracex[i] = 0;ant[AntNow].tracey[i] = 0;}ant[AntNow].TracePtr = 0;/* a sepecail ant */if(AntNow==0) ant[AntNow].speed = INI_SPEED;}void WorldChange(void){int k,i,j;int smelldisp;SmellGoneTimer+=timer10ms;if(SmellGoneTimer>=SMELL_GONE_SPEED){SmellGoneTimer = 0;for(k=0;k<=1;k++)/* SMELL TYPE FOOD and HOME */for(i=1;i<=MAXX;i++)for(j=1;j<=MAXY;j++){if(Smell[k][i][j]){smelldisp = 1+((10*Smell[k][i][j])/(MAX_SMELL*SMELL_DROP_RATE)); if(smelldisp>=30000||smelldisp<0) smelldisp = 30000;if(SmellDispFlag){gotoxy(i,j);if((i==food.xxx&&j==food.yyy)||(i==home.xxx&&j==home.yyy))/* don't over write Food and Home */;else{if(smelldisp>9) putch('#');else putch(smelldisp+'0');}}Smell[k][i][j]-= 1+(Smell[k][i][j]*SMELL_GONE_RATE);if(Smell[k][i][j]<0) Smell[k][i][j] = 0;if(SmellDispFlag){if(Smell[k][i][j]<=2){gotoxy(i,j);putch(SPACE);}}}} /* of one location */} /* of time to change the world */} /* of world change */void AntMove(void){int antx,anty;int smelltodrop,smellnow;for(AntNow=0;AntNow<MAX_ANT;AntNow++){ant[AntNow].SpeedTimer+=timer10ms;if(ant[AntNow].SpeedTimer>=ant[AntNow].speed){ant[AntNow].SpeedTimer = 0;gotoxy(ant[AntNow].xxx,ant[AntNow].yyy);putch(SPACE);AntOneStep();gotoxy(ant[AntNow].xxx,ant[AntNow].yyy);/* ant0 is a sepecail ant, use different color */if(AntNow==0) textcolor(0xd);if(ant[AntNow].food) putch(ANT_CHAR_FOOD);else putch(ANT_CHAR_EMPTY);if(AntNow==0) textcolor(0x7);/* remember trace */ant[AntNow].tracex[ant[AntNow].TracePtr] = ant[AntNow].xxx;ant[AntNow].tracey[ant[AntNow].TracePtr] = ant[AntNow].yyy;if(++(ant[AntNow].TracePtr)>=TRACE_REMEMBER) ant[AntNow].TracePtr = 0;/* drop smell */antx = ant[AntNow].xxx;anty = ant[AntNow].yyy;if(ant[AntNow].food)/* have food, looking for home */{if(ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]){smellnow = Smell[SMELL_TYPE_FOOD][antx][anty];smelltodrop = ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]*SMELL_DROP_RATE;if(smelltodrop>smellnow) Smell[SMELL_TYPE_FOOD][antx][anty] = smelltodrop;/* else Smell[...] = smellnow */ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]-= smelltodrop;if(ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]<0) ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = 0; } /* of have smell to drop */} /* of have food */else/* no food, looking for food */{if(ant[AntNow].SmellAmount[SMELL_TYPE_HOME]){smellnow = Smell[SMELL_TYPE_HOME][antx][anty];smelltodrop = ant[AntNow].SmellAmount[SMELL_TYPE_HOME]*SMELL_DROP_RATE;if(smelltodrop>smellnow) Smell[SMELL_TYPE_HOME][antx][anty] = smelltodrop;/* else Smell[...] = smellnow */ant[AntNow].SmellAmount[SMELL_TYPE_HOME]-= smelltodrop;if(ant[AntNow].SmellAmount[SMELL_TYPE_HOME]<0) ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = 0; } /* of have smell to drop */}} /* of time to go *//* else not go */} /* of for AntNow */textcolor(FOOD_HOME_COLOR);gotoxy(home.xxx,home.yyy); putch(HOME_CHAR);gotoxy(food.xxx,food.yyy);if(food.amount>0) putch(FOOD_CHAR);else putch(FOOD_CHAR2);textcolor(7);gotoxy(1,MAXY+1);printf("Food %d, Home %d ",food.amount,home.amount);}void AntOneStep(void){int ddir,tttx,ttty;int i;ddir = ant[AntNow].dir;tttx = ant[AntNow].xxx;ttty = ant[AntNow].yyy;ddir = AntNextDir(tttx,ttty,ddir);switch(ddir){case UP: ttty--;break;case DOWN: ttty++;break;case LEFT: tttx--;break;case RIGHT: tttx++;break;default: break;} /* of switch dir */ant[AntNow].dir = ddir;ant[AntNow].xxx = tttx;ant[AntNow].yyy = ttty;if(ant[AntNow].food)/* this ant carry with food, search for home */{if(tttx==home.xxx&&ttty==home.yyy){home.amount++;AntInitial();}if(tttx==food.xxx&&ttty==food.yyy)ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = MAX_SMELL; } /* of search for home */else/* this ant is empty, search for food */{if(tttx==food.xxx&&ttty==food.yyy){if(food.amount>0){ant[AntNow].food = 1;food.amount--;ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = MAX_SMELL; ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = 0;ant[AntNow].dir = TurnBack(ant[AntNow].dir);for(i=0;i<TRACE_REMEMBER;i++){ant[AntNow].tracex[i] = 0;ant[AntNow].tracey[i] = 0;}ant[AntNow].TracePtr = 0;CanFindFood = 1;} /* of still have food */}if(tttx==home.xxx&&ttty==home.yyy)ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = MAX_SMELL; } /* of search for food */}void DealKey(char key){int i;switch(key){case 'p': gettime(&endtime);DispPlayTime();getch();gotoxy(1,MAXY+1);for(i=1;i<=MAXX-1;i++) putch(SPACE); break;case 't': if(SmellDispFlag){SmellDispFlag=0;ClearSmellDisp();}else SmellDispFlag = 1;break;case '1': DispSmell(SMELL_TYPE_FOOD); getch();ClearSmellDisp();break;case '2': DispSmell(SMELL_TYPE_HOME); getch();ClearSmellDisp();break;case '3': DispSmell(2);getch();ClearSmellDisp();break;case 's': SaveBlock();break;case 'l': LoadBlock();break;default: gotoxy(1,MAXY+1);for(i=1;i<=MAXX-1;i++) putch(SPACE); } /* of switch */}void ClearSmellDisp(void){int k,i,j;for(k=0;k<=1;k++)/* SMELL TYPE FOOD and HOME */for(i=1;i<=MAXX;i++)for(j=1;j<=MAXY;j++){if(Smell[k][i][j]){gotoxy(i,j);putch(SPACE);}} /* of one location */}void DispSmell(int type)/* input: 0 -- Only display food smell1 -- Only display home smell2 -- Display both food and home smell*/{int k,i,j;int fromk,tok;int smelldisp;switch(type){case 0: fromk = 0;tok = 0;break;case 1: fromk = 1;tok = 1;break;case 2: fromk = 0;tok = 1;break;default:fromk = 0;tok = 1;break;}SmellGoneTimer = 0;for(k=fromk;k<=tok;k++)/* SMELL TYPE FOOD and HOME */for(i=1;i<=MAXX;i++)for(j=1;j<=MAXY;j++){if(Smell[k][i][j]){smelldisp = 1+((10*Smell[k][i][j])/(MAX_SMELL*SMELL_DROP_RATE)); if(smelldisp>=30000||smelldisp<0) smelldisp = 30000;gotoxy(i,j);if(i!=food.xxx||j!=food.yyy){if((i==food.xxx&&j==food.yyy)||(i==home.xxx&&j==home.yyy))/* don't over write Food and Home */;else{if(smelldisp>9) putch('#');else putch(smelldisp+'0');}}}} /* of one location */}int AntNextDir(int xxx,int yyy,int ddir){int randnum;int testdir;int CanGoState;int cangof,cangol,cangor;int msf,msl,msr,maxms;int type;CanGoState = CanGo(xxx,yyy,ddir);if(CanGoState==0||CanGoState==2||CanGoState==3||CanGoState==6) cangof = 1; else cangof = 0;if(CanGoState==0||CanGoState==1||CanGoState==3||CanGoState==5) cangol = 1; else cangol = 0;if(CanGoState==0||CanGoState==1||CanGoState==2||CanGoState==4) cangor = 1; else cangor = 0;if(ant[AntNow].food) type = SMELL_TYPE_HOME;else type = SMELL_TYPE_FOOD;msf = GetMaxSmell(type,xxx,yyy,ddir);msl = GetMaxSmell(type,xxx,yyy,TurnLeft(ddir));msr= GetMaxSmell(type,xxx,yyy,TurnRight(ddir));maxms = MaxLocation(msf,msl,msr);/* maxms - 1 - msf is MAX2 - msl is MAX3 - msr is MAX0 - all 3 number is 0 */testdir = NULL;switch(maxms){case 0: /* all is 0, keep testdir = NULL, random select dir */break;case 1: if(cangof)testdir = ddir;elseif(msl>msr) if(cangol) testdir = TurnLeft(ddir);else if(cangor) testdir = TurnRight(ddir);break;case 2: if(cangol)testdir = TurnLeft(ddir);elseif(msf>msr) if(cangof) testdir = ddir;else if(cangor) testdir = TurnRight(ddir);break;case 3: if(cangor)testdir = TurnRight(ddir);elseif(msf>msl) if(cangof) testdir =ddir;else if(cangol) testdir = TurnLeft(ddir);break;default:break;} /* of maxms */randnum = random(1000);if(randnum<SMELL_DROP_RATE*1000||testdir==NULL)/* 1. if testdir = NULL, means can not find the max smell or the dir to max smell can not go then random select dir2. if ant error, don't follow the smell, random select dir*/{randnum = random(100);switch(CanGoState){case 0: if(randnum<90) testdir = ddir;else if (randnum>=90&&randnum<95) testdir = TurnLeft(ddir);else testdir = TurnRight(ddir);break;case 1: if(randnum<50) testdir = TurnLeft(ddir);else testdir = TurnRight(ddir);break;case 2: if(randnum<90) testdir = ddir;else testdir = TurnRight(ddir);break;case 3: if(randnum<90) testdir = ddir;else testdir = TurnLeft(ddir);break;case 4: testdir = TurnRight(ddir);break;case 5: testdir = TurnLeft(ddir);break;case 6: testdir = ddir;break;case 7: testdir = TurnBack(ddir);break;default:testdir = TurnBack(ddir);} /* of can go state */}return(testdir);}int GetMaxSmell(int type,int xxx,int yyy,int ddir){int i,j;int ms; /* MAX smell */ms = 0;switch(ddir){case UP: for(i=xxx-ANT_EYESHOT;i<=xxx+ANT_EYESHOT;i++)for(j=yyy-ANT_EYESHOT;j<yyy;j++){if(!JudgeCanGo(i,j)) continue;if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)||(i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)){ms = MAX_SMELL;break;}if(IsTrace(i,j)) continue;if(Smell[type][i][j]>ms) ms = Smell[type][i][j];}break;case DOWN: for(i=xxx-ANT_EYESHOT;i<=xxx+ANT_EYESHOT;i++)for(j=yyy+1;j<=yyy+ANT_EYESHOT;j++){if(!JudgeCanGo(i,j)) continue;if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) {ms = MAX_SMELL;break;}if(IsTrace(i,j)) continue;if(Smell[type][i][j]>ms) ms = Smell[type][i][j];}break;case LEFT: for(i=xxx-ANT_EYESHOT;i<xxx;i++)for(j=yyy-ANT_EYESHOT;j<=yyy+ANT_EYESHOT;j++){if(!JudgeCanGo(i,j)) continue;if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) {ms = MAX_SMELL;break;}if(IsTrace(i,j)) continue;if(Smell[type][i][j]>ms) ms = Smell[type][i][j];}break;case RIGHT: for(i=xxx+1;i<=xxx+ANT_EYESHOT;i++)for(j=yyy-ANT_EYESHOT;j<=yyy+ANT_EYESHOT;j++){if(!JudgeCanGo(i,j)) continue;if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) {ms = MAX_SMELL;break;}if(IsTrace(i,j)) continue;if(Smell[type][i][j]>ms) ms = Smell[type][i][j];}break;default: break;}return(ms);}int IsTrace(int xxx,int yyy){int i;for(i=0;i<TRACE_REMEMBER;i++)if(ant[AntNow].tracex[i]==xxx&&ant[AntNow].tracey[i]==yyy) return(1);return(0);}int MaxLocation(int num1,int num2,int num3){int maxnum;if(num1==0&&num2==0&&num3==0) return(0);maxnum = num1;if(num2>maxnum) maxnum = num2;if(num3>maxnum) maxnum = num3;if(maxnum==num1) return(1);if(maxnum==num2) return(2);if(maxnum==num3) return(3);}int CanGo(int xxx,int yyy,int ddir)/* input: xxx,yyy - location of antddir - now diroutput: 0 - forward and left and right can go1 - forward can not go2 - left can not go3 - right can not go4 - forward and left can not go5 - forward and right can not go6 - left and right can not go7 - forward and left and right all can not go */{int tx,ty,tdir;int okf,okl,okr;/* forward can go ? */tdir = ddir;tx = xxx;ty = yyy;switch(tdir){case UP: ty--;break;case DOWN: ty++;break;case LEFT: tx--;break;case RIGHT: tx++;break;default: break;} /* of switch dir */if(JudgeCanGo(tx,ty)) okf = 1;else okf = 0;/* turn left can go ? */tdir = TurnLeft(ddir);tx = xxx;ty = yyy;switch(tdir){case UP: ty--;break;case DOWN: ty++;break;case LEFT: tx--;break;case RIGHT: tx++;break;default: break;} /* of switch dir */if(JudgeCanGo(tx,ty)) okl = 1;else okl = 0;/* turn right can go ? */tdir = TurnRight(ddir);tx = xxx;ty = yyy;switch(tdir){case UP: ty--;break;case DOWN: ty++;break;case LEFT: tx--;break;case RIGHT: tx++;break;default: break;} /* of switch dir */if(JudgeCanGo(tx,ty)) okr = 1;else okr = 0;if(okf&&okl&&okr) return(0);if(!okf&&okl&&okr) return(1);if(okf&&!okl&&okr) return(2);if(okf&&okl&&!okr) return(3);if(!okf&&!okl&&okr) return(4);if(!okf&&okl&&!okr) return(5);if(okf&&!okl&&!okr) return(6);if(!okf&&!okl&&!okr) return(7);return(7);}int JudgeCanGo(int xxx,int yyy)/* input: location to judegoutput: 0 -- can not go1 -- can go*/{int i,j;if(xxx<=0||xxx>MAXX) return(0);if(yyy<=0||yyy>MAXY) return(0);if(block[xxx][yyy]) return(0);return(1);}int TurnLeft(int ddir){switch(ddir){case UP: return(LEFT);case DOWN: return(RIGHT);case LEFT: return(DOWN);case RIGHT: return(UP);default: break;} /* of switch dir */}int TurnRight(int ddir){switch(ddir){case UP: return(RIGHT);case DOWN: return(LEFT);case LEFT: return(UP);case RIGHT: return(DOWN);default: break;} /* of switch dir */}int TurnBack(int ddir){switch(ddir){case UP: return(DOWN);case DOWN: return(UP);case LEFT: return(RIGHT);case RIGHT: return(LEFT);default: break;} /* of switch dir */}算法解释:程序开始运⾏,蚂蚁们开始从窝⾥出动了,寻找⾷物;他们会顺着屏幕爬满整个画⾯,直到找到⾷物再返回窝。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.#include<iostream>2.#include<math.h>3.#include<time.h>ing namespace std;5.6.//该程序是以蚁群系统为模型写的蚁群算法程序(强调:非蚂蚁周模型),以三个著名的TSP问题为测试对象7.//通过微调参数,都可以获得较好的解8.9./*10.//----------(1)问题一:Oliver 30 城市 TSP 问题 best_length = 423.7406; ------------------------11.//该程序最好的结果是423.741,可运行多次获得12.//城市节点数目13.#define N 3014.//城市坐标15.double C[N][2]={16. {2,99},{4,50},{7,64},{13,40},{18,54},{18,40},{22,60},{24,42},{25,62},{25,38},17. {37,84},{41,94},{41,26},{44,35},{45,21},{54,67},{54,62},{58,35},{58,69},{62,32},18. {64,60},{68,58},{71,44},{71,71},{74,78},{82,7},{83,46},{83,69},{87,76},{91,38}19.};20.//----------上面参数是固定的,下面的参数是可变的-----------21.//蚂蚁数量22.#define M 3023.//最大循环次数NcMax24.int NcMax = 500;25.//信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q026.double alpha = 2, beta = 3, rou = 0.1, alpha1 = 0.1, qzero = 0.01;27.//-----------问题一结束------------------------------------------------------------------------28.*/29.30./*31.//----------(2)问题二:Elion50 城市 TSP 问题 best_length = 427.96; ----------------------------32.//该程序最好的结果是428.468,可运行多次获得33.//城市节点数目34.#define N 5035.//城市坐标36.double C[N][2]={37. {5,64}, {5,25}, {5,6}, {7,38}, {8,52}, {10,17},38. {12,42}, {13,13}, {16,57}, {17,33}, {17,63},39. {20,26}, {21,47}, {21,10}, {25,32}, {25,55},40. {27,68}, {27,23}, {30,48}, {30,15}, {31,62},41. {31,32}, {32,22}, {32,39}, {36,16}, {37,69},42. {37,52}, {38,46}, {39,10}, {40,30}, {42,57},43. {42,41}, {43,67}, {45,35}, {46,10}, {48,28},44. {49,49}, {51,21}, {52,33}, {52,41}, {52,64},45. {56,37}, {57,58}, {58,27}, {58,48}, {59,15},46. {61,33}, {62,42}, {62,63}, {63,69}47.};48.//----------上面参数是固定的,下面的参数是可变的-----------49.//蚂蚁数量50.#define M 5051.//最大循环次数NcMax52.int NcMax = 1000;53.//信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q054.double alpha = 2, beta = 4, rou = 0.1, alpha1 = 0.1, qzero = 0.01;55.//-----------问题二结束------------------------------------------------------------------------56.*/57.58.//----------(3)问题三:Elion75 城市 TSP 问题 best_length = 542.31;59.//该程序最好的结果是542.309,可运行多次获得60.//城市节点数目61.#define N 7562.//城市坐标63.double C[N][2]={64.{6,25}, {7,43}, {9,56}, {10,70}, {11,28},65.{12,17}, {12,38}, {15,5}, {15,14}, {15,56},66.{16,19}, {17,64}, {20,30}, {21,48}, {21,45},67.{21,36}, {22,53}, {22,22}, {26,29}, {26,13},68.{26,59}, {27,24}, {29,39}, {30,50}, {30,20},69.{30,60}, {31,76}, {33,34}, {33,44}, {35,51},70.{35,16}, {35,60}, {36,6}, {36,26}, {38,33},71.{40,37}, {40,66}, {40,60}, {40,20}, {41,46},72.{43,26}, {44,13}, {45,42}, {45,35}, {47,66},73.{48,21}, {50,30}, {50,40}, {50,50}, {50,70},74.{50,4}, {50,15}, {51,42}, {52,26}, {54,38},75.{54,10}, {55,34}, {55,45}, {55,50}, {55,65},76.{55,57}, {55,20}, {57,72}, {59,5}, {60,15},77.{62,57}, {62,48}, {62,35}, {62,24}, {64,4},78.{65,27}, {66,14}, {66,8}, {67,41}, {70,64}80.//----------上面参数是固定的,下面的参数是可变的-----------81.//蚂蚁数量82.#define M 7583.//最大循环次数NcMax84.int NcMax =1000;85.//信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q086.double alpha = 2, beta = 5, rou = 0.1, alpha1 = 0.1, qzero = 0.1;87.//-----------问题三结束------------------------------------------------------------------------88.89.90.//===========================================================================================================91.//局部更新时候使用的的常量,它是由最近邻方法得到的一个长度92.//什么是最近邻方法?:)就是从源节点出发,每次选择一个距离最短的点来遍历所有的节点得到的路径93.//每个节点都可能作为源节点来遍历94.double Lnn;95.//矩阵表示两两城市之间的距离96.double allDistance[N][N];97.98.//计算两个城市之间的距离99.double calculateDistance(int i, int j)100.{101.return sqrt(pow((C[i][0]-C[j][0]),2.0) + pow((C[i][1]-C[j][1]),2.0)); 102.}103.104.//由矩阵表示两两城市之间的距离105.void calculateAllDistance()106.{107.for(int i = 0; i < N; i++)108. {109.for(int j = 0; j < N; j++)110. {111.if (i != j)112. {113. allDistance[i][j] = calculateDistance(i, j);114. allDistance[j][i] = allDistance[i][j];115. }116. }117. }118.}120.//获得经过n个城市的路径长度121.double calculateSumOfDistance(int* tour)122.{123.double sum = 0;124.for(int i = 0; i< N ;i++)125. {126.int row = *(tour + 2 * i);127.int col = *(tour + 2* i + 1);128. sum += allDistance[row][col];129. }130.return sum;131.}132.133.class ACSAnt;134.135.class AntColonySystem136.{137.private:138.double info[N][N], visible[N][N];//节点之间的信息素强度,节点之间的能见度139.public:140. AntColonySystem()141. {142. }143.//计算当前节点到下一节点转移的概率144.double Transition(int i, int j);145.//局部更新规则146.void UpdateLocalPathRule(int i, int j);147.//初始化148.void InitParameter(double value);149.//全局信息素更新150.void UpdateGlobalPathRule(int* bestTour, int globalBestLength); 151.};152.153.//计算当前节点到下一节点转移的概率154.double AntColonySystem::Transition(int i, int j)155.{156.if (i != j)157. {158.return (pow(info[i][j],alpha) * pow(visible[i][j], beta)); 159. }160.else161. {162.return 0.0;163. }164.}165.//局部更新规则166.void AntColonySystem::UpdateLocalPathRule(int i, int j)167.{168. info[i][j] = (1.0 - alpha1) * info[i][j] + alpha1 * (1.0 / (N * Lnn));169. info[j][i] = info[i][j];170.}171.//初始化172.void AntColonySystem::InitParameter(double value)173.{174.//初始化路径上的信息素强度tao0175.for(int i = 0; i < N; i++)176. {177.for(int j = 0; j < N; j++)178. {179. info[i][j] = value;180. info[j][i] = value;181.if (i != j)182. {183. visible[i][j] = 1.0 / allDistance[i][j];184. visible[j][i] = visible[i][j];185. }186. }187. }188.}189.190.//全局信息素更新191.void AntColonySystem::UpdateGlobalPathRule(int* bestTour, int globalBestLen gth)192.{193.for(int i = 0; i < N; i++)194. {195.int row = *(bestTour + 2 * i);196.int col = *(bestTour + 2* i + 1);197. info[row][col] = (1.0 - rou) * info[row][col] + rou * (1.0 / global BestLength);198. info[col][row] =info[row][col];199. }200.}201.202.class ACSAnt203.{204.private:205. AntColonySystem* antColony;206.protected:207.int startCity, cururentCity;//初始城市编号,当前城市编号208.int allowed[N];//禁忌表209.int Tour[N][2];//当前路径210.int currentTourIndex;//当前路径索引,从0开始,存储蚂蚁经过城市的编号211.public:212. ACSAnt(AntColonySystem* acs, int start)213. {214. antColony = acs;215. startCity = start;216. }217.//开始搜索218.int* Search();219.//选择下一节点220.int Choose();221.//移动到下一节点222.void MoveToNextCity(int nextCity);223.224.};225.226.//开始搜索227.int* ACSAnt::Search()228.{229. cururentCity = startCity;230.int toCity;231. currentTourIndex = 0;232.for(int i = 0; i < N; i++)233. {234. allowed[i] = 1;235. }236. allowed[cururentCity] = 0;237.int endCity;238.int count = 0;239.do240. {241. count++;242. endCity = cururentCity;243. toCity = Choose();244.if (toCity >= 0)245. {246. MoveToNextCity(toCity);247. antColony->UpdateLocalPathRule(endCity, toCity);248. cururentCity = toCity;249. }250. }while(toCity >= 0);251. MoveToNextCity(startCity);252. antColony->UpdateLocalPathRule(endCity, startCity);253.254.return *Tour;255.}256.257.//选择下一节点258.int ACSAnt::Choose()259.{260.int nextCity = -1;261.double q = rand()/(double)RAND_MAX;262.//如果 q <= q0,按先验知识,否则则按概率转移,263.if (q <= qzero)264. {265.double probability = -1.0;//转移到下一节点的概率266.for(int i = 0; i < N; i++)267. {268.//去掉禁忌表中已走过的节点,从剩下节点中选择最大概率的可行节点269.if (1 == allowed[i])270. {271.double prob = antColony->Transition(cururentCity, i); 272.if (prob > probability)273. {274. nextCity = i;275. probability = prob;276. }277. }278. }279. }280.else281. {282.//按概率转移283.double p = rand()/(double)RAND_MAX;//生成一个随机数,用来判断落在哪个区间段284.double sum = 0.0;285.double probability = 0.0;//概率的区间点,p 落在哪个区间段,则该点是转移的方向286.//计算概率公式的分母的值287.for(int i = 0; i < N; i++)288. {289.if (1 == allowed[i])291. sum += antColony->Transition(cururentCity, i);292. }293. }294.for(int j = 0; j < N; j++)295. {296.if (1 == allowed[j] && sum > 0)297. {298. probability += antColony->Transition(cururentCity, j)/sum;299.if (probability >= p || (p > 0.9999 && probability > 0.9999 ))300. {301. nextCity = j;302.break;303. }304. }305. }306. }307.return nextCity;308.}309.310.//移动到下一节点311.void ACSAnt::MoveToNextCity(int nextCity)312.{313. allowed[nextCity]=0;314. Tour[currentTourIndex][0] = cururentCity;315. Tour[currentTourIndex][1] = nextCity;316. currentTourIndex++;317. cururentCity = nextCity;318.}319.320.//------------------------------------------321.//选择下一个节点,配合下面的函数来计算的长度322.int ChooseNextNode(int currentNode, int visitedNode[])323.{324.int nextNode = -1;325.double shortDistance = 0.0;326.for(int i = 0; i < N; i++)327. {328.//去掉已走过的节点,从剩下节点中选择距离最近的节点329.if (1 == visitedNode[i])330. {331.if (shortDistance == 0.0)333. shortDistance = allDistance[currentNode][i]; 334. nextNode = i;335. }336.if(shortDistance < allDistance[currentNode][i]) 337. {338. nextNode = i;339. }340. }341. }342.return nextNode;343.}344.345.//给一个节点由最近邻距离方法计算长度346.double CalAdjacentDistance(int node)347.{348.double sum = 0.0;349.int visitedNode[N];350.for(int j = 0; j < N; j++)351. {352. visitedNode[j] = 1;353. }354. visitedNode[node] = 0;355.int currentNode = node;356.int nextNode;357.do358. {359. nextNode = ChooseNextNode(currentNode, visitedNode); 360.if (nextNode >= 0)361. {362. sum += allDistance[currentNode][nextNode]; 363. currentNode= nextNode;364. visitedNode[currentNode] = 0;365. }366. }while(nextNode >= 0);367. sum += allDistance[currentNode][node];368.return sum;369.}370.371.//---------------------------------结束---------------------------------------------372.373.//--------------------------主函数--------------------------------------------------374.int main()375.{376.time_t timer,timerl;377.378. time(&timer);379. unsigned long seed = timer;380. seed %= 56000;381. srand((unsigned int)seed);382.383.//由矩阵表示两两城市之间的距离384. calculateAllDistance();385.//蚁群系统对象386. AntColonySystem* acs = new AntColonySystem();387. ACSAnt* ants[M];388.//蚂蚁均匀分布在城市上389.for(int k = 0; k < M; k++)390. {391. ants[k] = new ACSAnt(acs, (int)(k%N));392. }393. calculateAllDistance();394.//随机选择一个节点计算由最近邻方法得到的一个长度395.int node = rand() % N;396. Lnn = CalAdjacentDistance(node);397.398.//各条路径上初始化的信息素强度399.double initInfo = 1 / (N * Lnn);400. acs->InitParameter(initInfo);401.402.//全局最优路径403.int globalTour[N][2];404.//全局最优长度405.double globalBestLength = 0.0;406.for(int i = 0; i < NcMax; i++)407. {408.//局部最优路径409.int localTour[N][2];410.//局部最优长度411.double localBestLength = 0.0;412.//当前路径长度413.double tourLength;414.for(int j = 0; j < M; j++)415. {416.int* tourPath = ants[j]->Search();417. tourLength = calculateSumOfDistance(tourPath);418.//局部比较,并记录路径和长度419.if(tourLength < localBestLength || abs(localBestLength - 0.0) <0.000001)420. {421.for(int m = 0; m< N; m++)422. {423.int row = *(tourPath + 2 * m);424.int col = *(tourPath + 2* m + 1);425. localTour[m][0] = row;426. localTour[m][1] = col;427. }428. localBestLength = tourLength;429. }430. }431.//全局比较,并记录路径和长度432.if(localBestLength < globalBestLength || abs(globalBestLength - 0.0 ) < 0.000001)433. {434.for(int m = 0; m< N; m++)435. {436. globalTour[m][0] = localTour[m][0];437. globalTour[m][1] = localTour[m][1];438. }439. globalBestLength = localBestLength;440. }441. acs->UpdateGlobalPathRule(*globalTour, globalBestLength);442.//输出所有蚂蚁循环一次后的迭代最优路径443. cout<<"第 "<<i + 1<<" 迭代最优路径:"<<localBestLength<<"."<<endl; 444.for(int m = 0; m< N; m++)445. {446. cout<<localTour[m][0]<<".";447. }448. cout<<endl;449. }450.//输出全局最优路径451. cout<<"全局最优路径长度:"<<globalBestLength<<endl;452. cout<<"全局最优路径:";453.for(int m = 0; m< N; m++)454. {455. cout<<globalTour[m][0]<<".";456. }457. cout<<endl;458. time(&timerl);459.int t = timerl - timer;460.return 0;461.}462.//--------------------------主函数结束--------------------------------------------------。