基本蚁群算法的c源程序
蚁群算法及案例分析精选全文
群在选择下一条路径的时
候并不是完全盲目的,而是
按一定的算法规律有意识
地寻找最短路径
自然界蚁群不具有记忆的
能力,它们的选路凭借外
激素,或者道路的残留信
息来选择,更多地体现正
反馈的过程
人工蚁群和自然界蚁群的相似之处在于,两者优先选择的都
是含“外激素”浓度较大的路径; 两者的工作单元(蚂蚁)都
正反馈、较强的鲁棒性、全
局性、普遍性
局部搜索能力较弱,易出现
停滞和局部收敛、收敛速度
慢等问题
优良的分布式并行计算机制
长时间花费在解的构造上,
导致搜索时间过长
Hale Waihona Puke 易于与其他方法相结合算法最先基于离散问题,不
能直接解决连续优化问题
蚁群算法的
特点
蚁群算法的特点及应用领域
由于蚁群算法对图的对称性以
及目标函数无特殊要求,因此
L_ave=zeros(NC_max,1);
%各代路线的平均长度
while NC<=NC_max
%停止条件之一:达到最大迭代次数
% 第二步:将m只蚂蚁放到n个城市上
Randpos=[];
for i=1:(ceil(m/n))
Randpos=[Randpos,randperm(n)];
end
Tabu(:,1)=(Randpos(1,1:m))';
scatter(C(:,1),C(:,2));
L(i)=L(i)+D(R(1),R(n));
hold on
end
plot([C(R(1),1),C(R(N),1)],[C(R(1),2),C(R(N),2)])
蚁群算法
蚁群算法报告及代码一、狼群算法狼群算法是基于狼群群体智能,模拟狼群捕食行为及其猎物分配方式,抽象出游走、召唤、围攻3种智能行为以及“胜者为王”的头狼产生规则和“强者生存”的狼群更新机制,提出一种新的群体智能算法。
算法采用基于人工狼主体的自下而上的设计方法和基于职责分工的协作式搜索路径结构。
如图1所示,通过狼群个体对猎物气味、环境信息的探知、人工狼相互间信息的共享和交互以及人工狼基于自身职责的个体行为决策最终实现了狼群捕猎的全过程。
二、布谷鸟算法布谷鸟算法布谷鸟搜索算法,也叫杜鹃搜索,是一种新兴启发算法CS算法,通过模拟某些种属布谷鸟的寄生育雏来有效地求解最优化问题的算法.同时,CS也采用相关的Levy飞行搜索机制蚁群算法介绍及其源代码。
具有的优点:全局搜索能力强、选用参数少、搜索路径优、多目标问题求解能力强,以及很好的通用性、鲁棒性。
应用领域:项目调度、工程优化问题、求解置换流水车间调度和计算智能三、差分算法差分算法主要用于求解连续变量的全局优化问题,其主要工作步骤与其他进化算法基本一致,主要包括变异、交叉、选择三种操作。
算法的基本思想是从某一随机产生的初始群体开始,利用从种群中随机选取的两个个体的差向量作为第三个个体的随机变化源,将差向量加权后按照一定的规则与第三个个体求和而产生变异个体,该操作称为变异。
然后,变异个体与某个预先决定的目标个体进行参数混合,生成试验个体,这一过程称之为交叉。
如果试验个体的适应度值优于目标个体的适应度值,则在下一代中试验个体取代目标个体,否则目标个体仍保存下来,该操作称为选择。
在每一代的进化过程中,每一个体矢量作为目标个体一次,算法通过不断地迭代计算,保留优良个体,淘汰劣质个体,引导搜索过程向全局最优解逼近。
四、免疫算法免疫算法是一种具有生成+检测的迭代过程的搜索算法。
从理论上分析,迭代过程中,在保留上一代最佳个体的前提下,遗传算法是全局收敛的。
五、人工蜂群算法人工蜂群算法是模仿蜜蜂行为提出的一种优化方法,是集群智能思想的一个具体应用,它的主要特点是不需要了解问题的特殊信息,只需要对问题进行优劣的比较,通过各人工蜂个体的局部寻优行为,最终在群体中使全局最优值突现出来,有着较快的收敛速度。
蚁群算法源代码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问题指导教师:李正学系 别:应用数学系班 级:2003级06班姓 名:王源学 号:200312082蚂蚁算法求解TSP问题摘 要蚂蚁算法是通过蚂蚁觅食而发展出的一种新的启发算法,该算法已经成功的解决了诸如TSP问题。
本文简要学习探讨了蚂蚁算法和TSP问题的基本内容,尝试解决一个实例问题并给出C语言算法。
关键词蚂蚁算法;TSP问题。
1 蚂蚁算法与TSP问题1.1 蚂蚁算法蚂蚁算法(Ant Colony Algorithm) 是由意大利学者M.Dorigo ,V. Manierio ,A. Collorni等人于二十世纪九十年代提出的一种新型的模拟进化算法。
受到人们对自然界中真实蚁群集体行为研究成果的启发,考虑到蚁群搜索食物的过程与旅行商问题的相似性,利用蚁群算法求解旅行商问题(Traveling Salesman Problem,TSP ) 、指派问题(AssignmentProblem)和调度问题( Scheduling Problem) ,取得了一些比较满意的实验结果。
蚁群算法是一种适应性好、鲁棒性强,具有正反馈结构的并行算法。
这些初步研究已显示出蚁群算法在求解复杂优化问题(特别是离散优化问题)方面的一些优越性,证明它是一种很有发展前景的方法。
蚂蚁算法在各个领域的应用,说明该算法有着广泛的适应性,但由于该算法出现的较晚,对其研究还处于起步阶段,远不如遗传算法、人工神经网络和模拟退火算法那样成熟。
算法的很多特性,如算法的收敛性,参数的设定都来自于大量实验统计结果,目前对该算法理论研究有待进一步加强。
经过研究发现,蚂蚁在觅食的过程中通过一种称之为信息素(Pheromone)的物质相互传递信息。
更具体地,蚂蚁在运动过程中能够在其所经过的路径上留下信息素,而且在运动过程中能够感受到这种信息素的存在及其强度,并以此指导自己的运动方向。
蚂蚁倾向于朝着信息素浓度高的方向前进,因此,由大量蚂蚁组成的蚁群的行为便表现出一种信息的正反馈现象:某一路径上走过的蚂蚁越多,则后来者选择该路径的概率就越大。
蚁群算法matlab源代码
function [Shortest_Route,Shortest_Length]=ACATSP(D,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 各代最佳路线的长度%% L_ave 各代路线的平均长度%%=========================================================================%%第一步:变量初始化n=size(D,1);for i=1:nD(i,i)=eps;endEta=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_max,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))。
蚁群算法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。
蚁群算法原理及在TSP中的应用(附程序)
蚁群算法原理及在TSP 中的应用1 蚁群算法(ACA )原理1.1 基本蚁群算法的数学模型以求解平面上一个n 阶旅行商问题(Traveling Salesman Problem ,TSP)为例来说明蚁群算法ACA (Ant Colony Algorithm )的基本原理。
对于其他问题,可以对此模型稍作修改便可应用。
TSP 问题就是给定一组城市,求一条遍历所有城市的最短回路问题。
设()i b t 表示t 时刻位于元素i 的蚂蚁数目,()ij t τ为t 时刻路径(,)i j 上的信息量,n 表示TSP 规模,m 为蚁群的总数目,则1()ni i m b t ==∑;{(),}ij i i t c c C τΓ=⊂是t 时刻集合C 中元素(城市)两两连接ij t 上残留信息量的集合。
在初始时刻各条路径上信息量相等,并设 (0)ij const τ=,基本蚁群算法的寻优是通过有向图(,,)g C L =Γ实现的。
蚂蚁(1,2,...,)k k m =在运动过程中,根据各条路径上的信息量决定其转移方向。
这里用禁忌表(1,2,...,)k tabu k m =来记录蚂蚁k 当前所走过的城市,集合随着k tabu 进化过程作动态调整。
在搜索过程中,蚂蚁根据各条路径上的信息量及路径的启发信息来计算状态转移概率。
()kij p t 表示在t 时刻蚂蚁k 由元素(城市)i 转移到元素(城市)j 的状态转移概率。
()*()()*()()0k ij ij k kij ij ij s allowed t t j allowed t t p t αβαβτητη⊂⎧⎡⎤⎡⎤⎣⎦⎣⎦⎪∈⎪⎡⎤⎡⎤=⎨⎣⎦⎣⎦⎪⎪⎩∑若否则(1)式中,{}k k allowed C tabuk =-表示蚂蚁k 下一步允许选择的城市;α为信息启发式因子,表示轨迹的相对重要性,反映了蚂蚁在运动过程中所积累的信息在蚂蚁运动时所起作用,其值越大,则该蚂蚁越倾向于选择其他蚂蚁经过的路径,蚂蚁之间协作性越强;β为期望启发式因子,表示能见度的相对重要性,反映了蚂蚁在运动过程中启发信息在蚂蚁选择路径中的重视程度,其值越大,则该状态转移概率越接近于贪心规则;()ij t η为启发函数,其表达式如下:1()ij ijt d η=(2)式中,ij d 表示相邻两个城市之间的距离。
蚁群算法C
这里发个贴吧里面的蚁群算法代码。
// AO.cpp : 定义控制台应用程序的入口点。
#pragma once#include <iostream>#include <math.h>#include <time.h>const double ALPHA=1.0; //启发因子,信息素的重要程度const double BETA=2.0; //期望因子,城市间距离的重要程度const double ROU=0.5; //信息素残留参数const int N_ANT_COUNT=34; //蚂蚁数量const int N_IT_COUNT=1000; //迭代次数const int N_CITY_COUNT=51; //城市数量const double DBQ=100.0; //总的信息素const double DB_MAX=10e9; //一个标志数,10的9次方double g_Trial[N_CITY_COUNT][N_CITY_COUNT]; //两两城市间信息素,就是环境信息素double g_Distance[N_CITY_COUNT][N_CITY_COUNT]; //两两城市间距离//eil51.tsp城市坐标数据double x_Ary[N_CITY_COUNT]={37,49,52,20,40,21,17,31,52,51,42,31,5,12,36,52,27,17,13,57,62,42,16,8,7,27,30,43,58,58,37,38,46,61,62,63,32,45,59,5,10,21,5,30,39,32,25,25,48,56,30};double y_Ary[N_CITY_COUNT]={52,49,64,26,30,47,63,62,33,21,41,32,25,42,16,41,23,33,13,58,42,57,57,52,38,68,48,67,48,27,69,46,10,33,63,69,22,35,15,6,17,10,64,15,10,39,32,55,28,37,40};//返回指定范围内的随机整数int rnd(int nLow,int nUpper){return nLow+(nUpper-nLow)*rand()/(RAND_MAX+1);}//返回指定范围内的随机浮点数double rnd(double dbLow,double dbUpper){double dbTemp=rand()/((double)RAND_MAX+1.0);return dbLow+dbTemp*(dbUpper-dbLow);}//返回浮点数四舍五入取整后的浮点数double ROUND(double dbA){return (double)((int)(dbA+0.5));}//定义蚂蚁类class CAnt{public:CAnt(void);~CAnt(void);public:int m_nPath[N_CITY_COUNT]; //蚂蚁走的路径double m_dbPathLength; //蚂蚁走过的路径长度int m_nAllowedCity[N_CITY_COUNT]; //没去过的城市 int m_nCurCityNo; //当前所在城市编号int m_nMovedCityCount; //已经去过的城市数量public:int ChooseNextCity(); //选择下一个城市void Init(); //初始化void Move(); //蚂蚁在城市间移动void Search(); //搜索路径void CalPathLength(); //计算蚂蚁走过的路径长度};//构造函数CAnt::CAnt(void){}//析构函数CAnt::~CAnt(void){}//初始化函数,蚂蚁搜索前调用void CAnt::Init(){for (int i=0;i<N_CITY_COUNT;i++){m_nAllowedCity[i]=1; //设置全部城市为没有去过 m_nPath[i]=0; //蚂蚁走的路径全部设置为0}//蚂蚁走过的路径长度设置为0m_dbPathLength=0.0;//随机选择一个出发城市m_nCurCityNo=rnd(0,N_CITY_COUNT);//把出发城市保存入路径数组中m_nPath[0]=m_nCurCityNo;//标识出发城市为已经去过了m_nAllowedCity[m_nCurCityNo]=0;//已经去过的城市数量设置为1m_nMovedCityCount=1;}//选择下一个城市//返回值为城市编号int CAnt::ChooseNextCity(){int nSelectedCity=-1; //返回结果,先暂时把其设置为-1//============================================================================ ==//计算当前城市和没去过的城市之间的信息素总和double dbTotal=0.0;double prob[N_CITY_COUNT]; //保存各个城市被选中的概率for (int i=0;i<N_CITY_COUNT;i++){if (m_nAllowedCity[i] == 1) //城市没去过{prob[i]=pow(g_Trial[m_nCurCityNo][i],ALPHA)*pow(1.0/g_Distance[m_nCurCityNo][i],BET A); //该城市和当前城市间的信息素dbTotal=dbTotal+prob[i]; //累加信息素,得到总和}else //如果城市去过了,则其被选中的概率值为0{prob[i]=0.0;}}//============================================================================ ==//进行轮盘选择double dbTemp=0.0;if (dbTotal > 0.0) //总的信息素值大于0{dbTemp=rnd(0.0,dbTotal); //取一个随机数for (int i=0;i<N_CITY_COUNT;i++){if (m_nAllowedCity[i] == 1) //城市没去过{dbTemp=dbTemp-prob[i]; //这个操作相当于转动轮盘,如果对轮盘选择不熟悉,仔细考虑一下if (dbTemp < 0.0) //轮盘停止转动,记下城市编号,直接跳出循环{nSelectedCity=i;break;}}}}//============================================================================ ==//如果城市间的信息素非常小( 小到比double能够表示的最小的数字还要小)//那么由于浮点运算的误差原因,上面计算的概率总和可能为0//会出现经过上述操作,没有城市被选择出来//出现这种情况,就把第一个没去过的城市作为返回结果//题外话:刚开始看的时候,下面这段代码困惑了我很长时间,想不通为何要有这段代码,后来才搞清楚。
蚁群算法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)])```需要注意的是,在使用蚁群算法求解优化问题时,需要先将问题转化为图论问题。
蚁群算法(C语言实现)
蚁群算法(C语⾔实现)蚁群算法(ant colony optimization, ACO),⼜称蚂蚁算法,是⼀种⽤来在图中寻找优化路径的机率型算法。
它由Marco Dorigo于1992年在他的中提出,其灵感来源于蚂蚁在寻找⾷物过程中发现路径的⾏为。
蚁群算法是⼀种模拟进化算法,初步的研究表明该算法具有许多优良的性质.针对参数优化设计问题,将蚁群算法设计的结果与遗传算法设计的结果进⾏了⽐较,数值仿真结果表明,蚁群算法具有⼀种新的模拟进化优化⽅法的有效性和应⽤价值。
预期的结果: 各个蚂蚁在没有事先告诉他们⾷物在什么地⽅的前提下开始寻找⾷物。
当⼀只找到⾷物以后,它会向⼀种信息素,吸引其他的蚂蚁过来,这样越来越多的蚂蚁会找到⾷物!有些蚂蚁并没有象其它蚂蚁⼀样总重复同样的路,他们会另辟蹊径,如果令开辟的道路⽐原来的其他道路更短,那么,渐渐,更多的蚂蚁被吸引到这条较短的路上来。
最后,经过⼀段时间运⾏,可能会出现⼀条最短的路径被⼤多数蚂蚁重复着。
原理: 为什么⼩⼩的蚂蚁能够找到⾷物?他们具有智能么?设想,如果我们要为蚂蚁设计⼀个⼈⼯智能的程序,那么这个程序要多么复杂呢?⾸先,你要让蚂蚁能够避开障碍物,就必须根据适当的地形给它编进指令让他们能够巧妙的避开障碍物,其次,要让蚂蚁找到⾷物,就需要让他们遍历空间上的所有点;再次,如果要让蚂蚁找到最短的路径,那么需要计算所有可能的路径并且⽐较它们的⼤⼩,⽽且更重要的是,你要⼩⼼翼翼的编程,因为程序的错误也许会让你前功尽弃。
这是多么不可思议的程序!太复杂了,恐怕没⼈能够完成这样繁琐冗余的程序。
然⽽,事实并没有你想得那么复杂,上⾯这个程序每个蚂蚁的核⼼程序编码不过100多⾏!为什么这么简单的程序会让蚂蚁⼲这样复杂的事情?答案是:简单规则的涌现。
事实上,每只蚂蚁并不是像我们想象的需要知道整个世界的信息,他们其实只关⼼很⼩范围内的眼前信息,⽽且根据这些局部信息利⽤⼏条简单的规则进⾏决策,这样,在蚁群这个集体⾥,复杂性的⾏为就会凸现出来。
智能计算之蚁群算法
第三章基本蚁群算法原理3.1 自然界中的蚂蚁在蚂蚁寻找食物的过程中,总能找到一条从蚁穴到随机分布的距离很远的食物源之间的最短路径。
仿生学家经过研究发现,蚂蚁没有视觉,但是在寻找食物的行进过程中,会不断分泌一种化学刺激物——信息素,蚂蚁之间通过它来相互通信。
信息素量与路径长度有关,路径越长,释放的信息素浓度就越低。
信息素可以吸引后来的蚂蚁沿信息素浓度高的路径行进。
某一路径上走过的蚂蚁越多,留下的信息素就越多,后来者选择该路径的概率就越大,蚂蚁个体之间就是通过这种信息的交流搜索食物,这样,由大量蚂蚁组成的蚁群的集体行为便表现出一种信息正反馈现象,整个蚁群最终会选择出最短路径行进。
图3.1 现实蚂蚁寻找食物如图3.1(a)所示,蚂蚁在点A和E之间的路径上行走,路径突然被出现的障碍物截断,如3.1(b)所示。
因此,蚂蚁从A至E步行至位置B (或以相反的方向在位置D处)必须决定是否要向左或向右转。
一开始蚂蚁按同等概率选择路径,不论路径长短。
第一只蚂蚁到达B点(或D)具有相同的概率向左或向右转。
由于路径BCD比BHD短,以路径BCD第一个到达的蚂蚁比以路径BHD到达的早。
由于一半蚂蚁是以偶然的方式通过DCBA障碍的或者已经通过路径BCD到达的,于是,一个蚂蚁从E 到D返回会在路径DCB上找到一个更强有力的线索。
因此他们极大概率上选择通过路径DCB而不是DHB。
因此,单位时间内通过路径BCD的蚂蚁要比通过路径BHD的蚂蚁多的多,如图3.1(c)。
这将导致较短路径上的信息素量增长地比较长路径上的快得多,因此单一蚂蚁路径的选择很快偏向于较短路径。
最后的结果是很快所有的蚂蚁会选择较短的路径[1]。
不仅如此,作为一种化学物质,信息素还具有挥发性,这使得寻径初期距离较长的路径和长期没有经过的路径对蚂蚁的影响逐渐减小。
可见,在整个寻找食物的过程中,虽然单个蚂蚁的选择能力有限,但是通过信息素的作用是整个蚁群行为具有非常高的自组织性,蚂蚁之间交换着路径信息,最终通过蚁群的集体自催化行为找出最优路径[3,4]。
蚁群算法 C语言程序(已运行)
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];
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 parameters
for(k=0;k<M;k++)
{
route[k][0]=k%N;
tabu[k][route[k][0]]=1;
}
//each ant try to find the optiamal path
do {
int s=1;
double partsum;
double pper;
double drand;
//ant choose one whole path
if(tao[i][j]>20)
tao[i][j]=20;
}
for(k=0;k<M;k++)
蚁群算法
蚁群算法求解TSP问题的源程序及简要说明该程序试图对具有31个城市的VRP进行求解,已知的最优解为784.1,我用该程序只能优化到810左右,应该是陷入局部最优,但我不知问题出在什么地方。
请用过蚁群算法的高手指教。
蚁群算法的matlab源码,同时请指出为何不能优化到已知的最好解%%% the procedure of ant colony algorithm for VRP%% % % % % % % % % % %%initialize the parameters of ant colony algorithmsload data.txt;d=data(:,2:3);g=data(:,4);m=31; % 蚂蚁数alpha=1;belta=4;% 决定tao和miu重要性的参数lmda=0;rou=0.9; %衰减系数q0=0.95;% 概率tao0=1/(31*841.04);%初始信息素Q=1;% 蚂蚁循环一周所释放的信息素defined_phrm=15.0; % initial pheromone level valueQV=100; % 车辆容量vehicle_best=round(sum(g)/QV)+1; %所完成任务所需的最少车数V=40;% 计算两点的距离for i=1:32;for j=1:32;dist(i,j)=sqrt((d(i,1)-d(j,1))^2+(d(i,2)-d(j,2))^2);end;end;%给tao miu赋初值for i=1:32;for j=1:32;if i~=j;%s(i,j)=dist(i,1)+dist(1,j)-dist(i,j);tao(i,j)=defined_phrm;miu(i,j)=1/dist(i,j);end;end;end;for k=1:32;for k=1:32;deltao(i,j)=0;end;end;best_cost=10000;for n_gen=1:50;print_head(n_gen);for i=1:m;%best_solution=[];print_head2(i);sumload=0;cur_pos(i)=1;rn=randperm(32);n=1;nn=1;part_sol(nn)=1;%cost(n_gen,i)=0.0;n_sol=0; % 由蚂蚁产生的路径数量M_vehicle=500;t=0; %最佳路径数组的元素数为0while sumload<=QV;for k=1:length(rn);if sumload+g(rn(k))<=QV;gama(cur_pos(i),rn(k))=(sumload+g(rn(k)))/QV;A(n)=rn(k);n=n+1;end;end;fid=fopen('out_customer.txt','a+');fprintf(fid,'%s %i\t','the current position is:',cur_pos(i));fprintf(fid,'\n%s','the possible customer set is:')fprintf(fid,'\t%i\n',A);fprintf(fid,'------------------------------\n');fclose(fid);p=compute_prob(A,cur_pos(i),tao,miu,alpha,belta,gama,lmda,i);maxp=1e-8;na=length(A);for j=1:na;if p(j)>maxpmaxp=p(j);index_max=j;end;end;old_pos=cur_pos(i);if rand(1)<q0cur_pos(i)=A(index_max);elsekrnd=randperm(na);cur_pos(i)=A(krnd(1));bbb=[old_pos cur_pos(i)];ccc=[1 1];if bbb==ccc;cur_pos(i)=A(krnd(2));end;end;tao(old_pos,cur_pos(i))=taolocalupdate(tao(old_pos,cur_pos(i)),rou,tao0);%对所经弧进行局部更新sumload=sumload+g(cur_pos(i));nn=nn+1;part_sol(nn)=cur_pos(i);temp_load=sumload;if cur_pos(i)~=1;rn=setdiff(rn,cur_pos(i));n=1;A=[];end;if cur_pos(i)==1; % 如果当前点为车场,将当前路径中的已访问用户去掉后,开始产生新路径if setdiff(part_sol,1)~=[];n_sol=n_sol+1; % 表示产生的路径数,n_sol=1,2,3,..5,6...,超过5条对其费用加上车辆的派遣费用fid=fopen('out_solution.txt','a+');fprintf(fid,'%s%i%s','NO.',n_sol,'条路径是:');fprintf(fid,'%i ',part_sol);fprintf(fid,'\n');fprintf(fid,'%s','当前的用户需求量是:');fprintf(fid,'%i\n',temp_load);fprintf(fid,'------------------------------\n');fclose(fid);% 对所得路径进行路径内3-opt优化final_sol=exchange(part_sol);for nt=1:length(final_sol); % 将所有产生的路径传给一个数组temp(t+nt)=final_sol(nt);end;t=t+length(final_sol)-1;sumload=0;final_sol=setdiff(final_sol,1);rn=setdiff(rn,final_sol);part_sol=[];final_sol=[];nn=1;part_sol(nn)=cur_pos(i);A=[];n=1;end;end;if setdiff(rn,1)==[];% 产生最后一条终点不为1的路径n_sol=n_sol+1;nl=length(part_sol);part_sol(nl+1)=1;%将路径的最后1位补1% 对所得路径进行路径内3-opt优化final_sol=exchange(part_sol);for nt=1:length(final_sol); % 将所有产生的路径传给一个数组temp(t+nt)=final_sol(nt);end;cost(n_gen,i)=cost_sol(temp,dist)+M_vehicle*(n_sol-vehicle_best); %计算由蚂蚁i产生的路径总长度for ki=1:length(temp)-1;deltao(temp(ki),temp(ki+1))=deltao(temp(ki),temp(ki+1))+Q/cost(n_gen,i);end;if cost(n_gen,i)<best_cost;best_cost=cost(n_gen,i);old_cost=best_cost;best_gen=n_gen; % 产生最小费用的代数best_ant=i; %产生最小费用的蚂蚁best_solution=temp;end;if i==m; %如果所有蚂蚁均完成一次循环,,则用最佳费用所对应的路径对弧进行整体更新for ii=1:32;for jj=1:32;tao(ii,jj)=(1-rou)*tao(ii,jj);end;end;for kk=1:length(best_solution)-1;tao(best_solution(kk),best_solution(kk+1))=tao(best_solution(kk),best_solution(kk+1))+de ltao(best_solution(kk),best_solution(kk+1));end;end;fid=fopen('out_solution.txt','a+');fprintf(fid,'%s%i%s','NO.',n_sol,'路径是:');fprintf(fid,'%i ',part_sol);fprintf(fid,'\n');fprintf(fid,'%s %i\n','当前的用户需求量是:',temp_load);fprintf(fid,'%s %f\n','总费用是:',cost(n_gen,i));fprintf(fid,'------------------------------\n');fprintf(fid,'%s\n','最终路径是:');fprintf(fid,'%i-',temp);fprintf(fid,'\n');fclose(fid);temp=[];break;end;end;end;end;我现在也在研究它,希望能共同进步.建义可以看一下段海滨的关于蚁群算法的书.讲的不错,李士勇的也可以,还有一本我在图书馆见过,记不得名字了简单蚁群算法求解TSP的源程序(我帮你找的)蚁群算法是新兴的仿生算法,最初是由意大利学者Dorigo M于1991年首次提出,由于具有较强的鲁棒性,优良的分布式计算机制和易于与其它方法结合等优点,成为人工智能领域的一个研究热点。
蚁群优化算法及编程实现
目录蚁群优化算法及编程实现 (III)摘要 (III)关键词 (III)Abstract (IV)Keywords (IV)第一章绪论 (1)1.1引言 (1)1.2课题背景 (1)1.2.1 蚁群优化算法在国外发展历史及发展趋势 (1)1.2.2蚁群优化算法在国内的发展趋势 (1)1.2.3设计要求及解决思路 (2)第二章蚁群优化系统原理 (3)2.1 蚁群优化算法的基本原理 (3)2,2蚁群优化算法的机制原理 (4)2.3 蚁群优化算法特征 (4)2.3.1 蚁群优化算法具有群体性 (4)2.3.2 蚁群优化算法就是一个完整的正反馈系统 (4)2.4 蚁群优化算法模型的建立 (5)2.4.1 对个体蚂蚁的抽象 (5)2.4.2 空间问题的描述 (5)2.4.3 寻找最优路径的抽象 (6)2.4.4 信息素挥发的抽象及计算 (6)第三章用蚁群优化算法解决TSP问题建模 (10)3.1什么是TSP? (10)3.2蚁群优化算法如何解决TSP问题 (10)3.3蚁群优化问题解决TSP问题的数学建模 (10)3.3.1 基本参数设定及计算 (10)3.4 程序难点介绍 (12)3.4.1 程序 (12)3.4.2 程序框图 (12)3.4.3 程序难点分析 (12)3.4.4 程序结构分析 (13)第四章用蚁群优化算法实现贵州旅游TSP问题 (14)4.1实验内容 (14)4.2贵州旅游景点坐标的提取 (14)4.3提取的景点及对应坐标 (15)4.4实验结果及分析 (17)4.4.1程序调试 (17)4.4.2调试结果 (17)4.4.3蚂蚁数量对于实验结果的影响分析 (19)第五章实现贵阳公交车连通所有大学的路径问题 (21)5.1贵阳所有大学的坐标 (21)5.2程序测试结果 (21)结语 (23)参考文献 (24)致谢 (25)附件 (26)蚁群优化算法及编程实现摘要蚁群优化算法是人工智能研究领域中一个非常重要重要的分支,蚁群优化算法最初是由意大利学者Ddorigo M与1991年首次提出来的,蚁群优化算法的本质就是一个非常复杂的智能化系统,而且这个系统还具有很强的鲁棒性(Robust)、比较好的分布式计算机制而且还能够与其他的相关方法相互结合使用的优点。
蚁群算法小程序(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 */}算法解释:程序开始运⾏,蚂蚁们开始从窝⾥出动了,寻找⾷物;他们会顺着屏幕爬满整个画⾯,直到找到⾷物再返回窝。
蚁群算法课程设计报告
图4-1
当次数为 时:
图4-2
图4-3
图4-4
图4-5
图4-6
图4-7
图4-8
图4-9
图4-10
最后运行结果:
图4-11
The shortest tours is : 430.000000.
下面的数字是51个城市所旅行的顺序,只要按照程序给出的城市顺序数进行旅行,所走的距离是最优的为430.
解决 个城市的TSP问题算法设计如下:
初始化:
设定 ,循环计数器 ,对每条路径设定初始信息量 , 将 只蚂蚁放在 个城市上(为了使问题简化,设定 )。
设定 集合的索引 ,对 从1到 ,把第 只蚂蚁放在起始位置,对应的设定集合
重复下面的步骤,直到集合 满为止(这一步将重复 次):
设定 ;
对 从1到 ,根据公式 确定的概率,选择下一步移动的目标城市 {在时间 时,第 只蚂蚁所在的城市是 };
17,10,64,15,10,39,32,55,28,37,
40.
求出最短的旅行距离。
求出如何旅行城市,求出每个城市是第几个旅行能使旅行距离最优。
第二章
程序设计内容
2.1关于蚁群智能和TSP
昆虫学家们在研究类似蚂蚁这样的视盲动物如何沿最佳路线从其巢穴打达食物源的过程中发现,蚂蚁与蚂蚁之间最重要的通信媒介就是他们在移动过程中所释放的特有的分泌物——信息素,当一个孤立的蚂蚁随机移动时,它能检测到其他同伴所释放的信息素,并沿着该路线移动,同时又释放自身的信息素,从而增强了该路线上的信息素数量,随着越来越多的蚂蚁通过该路线,一条最佳的路径就会逐渐形成。
2.2解决的问题
用蚁群算法来解决在旅行商旅中有51个城市的最优路径,并求出如何行走才是距离最短和城市走的顺序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基本蚁群算法的C++源程序/kekewutao2006-12-01 09:36关键词:蚁群算法C++源程序ACS基本蚁群算法的C++源程序//基本蚁群算法程序//程序在vc++6.0下面同过,对原来的做了一点修改。
//你可以使用本代码,如果感到对你有用的话,请通知作者,作者会很高兴。
//通讯地址:*****************//by FashionXu#include "stdafx.h"#include#include#include#includeusing namespace std;const int iAntCount=34;//蚂蚁数量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;class ant{private:int ChooseNextCity();//选择城市double prob[iCityCount];int m_iCityCount;int AllowedCity[iCityCount];//没有走过的城市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){addcity(i);break;}}void ant::Clear(){m_dLength=0;int i;for(i=0; i〈iCityCount;i++)prob[i]=0;AllowedCity[i]=1;}i=tabu[iCityCount-1];m_iCityCount=0;addcity(i);}ant::ant(){m_dLength=m_dShortest=0;m_iCityCount=0;int i;for(i=0;i〈iCityCount;i++)AllowedCity[i]=1;prob[i]=0;}}void ant::addcity(int city){//add city to tabu;tabu[m_iCityCount]=city;m_iCityCount++;AllowedCity[city]=0;}int ant::ChooseNextCity(){//Update the probability of path selection//select a path from tabu[m_iCityCount-1] to nextint i;int j=10000;double temp=0;int curCity=tabu[m_iCityCount-1];for (i=0;i〈iCityCount;i++)if((AllowedCity[i]==1)){temp+=pow((1.0/Map.distance[curCity][i]),beta)*pow((Map.m_dTria l[curCity][i]),alpha);}}double sel=0;for (i=0;i〈iCityCount;i++)if((AllowedCity[i]==1)){prob[i]=pow((1.0/Map.distance[curCity][i]),beta)*pow((Map.m_dTr ial[curCity][i]),alpha)/temp;sel+=prob[i];}elseprob[i]=0;}double mRate=rnd(0,sel);double mSelect=0;for ( i=0;i〈iCityCount;i++)if((AllowedCity[i]==1))mSelect+=prob[i] ;if (mSelect>=mRate) {j=i;break;}}if (j==10000){temp=-1;for (i=0;i〈iCityCount;i++)if((AllowedCity[i]==1))if (temp {temp=pow((1.0/Map.distance[curCity][i]),beta)*pow((Map.m_dT rial[curCity][i]),alpha);j=i;}}}return j;}void ant::UpdateResult(){// Update the length of tourint i;for(i=0;i〈iCityCount-1;i++)m_dLength+=Map.distance[tabu[i]][tabu[i+1]];m_dLength+=Map.distance[tabu[iCityCount-1]][tabu[0]];}void ant::move(){//the ant move to next town and add town ID to tabu.int j;j=ChooseNextCity();addcity(j);}class project{public:void UpdateTrial();double m_dLength;void initmap();ant ants[iAntCount];void GetAnt();void StartSearch();project();};void project::UpdateTrial(){//calculate the changes of trial informationint i;int j;for(i=0;i〈iAntCount;i++)for (j=0;j〈iCityCount-1;j++){ Map.m_dDeltTrial[ants[i].tabu[j]][ants[i].tabu[j+1]]+=Q/ants[i ].m_dLength ;Map.m_dDeltTrial[ants[i].tabu[j+1]][ants[i].tabu[j]]+=Q/ants[i] .m_dLength;}Map.m_dDeltTrial[ants[i].tabu[iCityCount-1]][ants[i].tabu[0]]+=Q/ ants[i].m_dLength;Map.m_dDeltTrial[ants[i].tabu[0]][ants[i].tabu[iCityCount-1]]+=Q/ ants[i].m_dLength;}for (i=0;i〈iCityCount;i++)for (j=0;j〈iCityCount;j++){Map.m_dTrial[i][j]=(rou*Map.m_dTrial[i][j]+Map.m_dDeltTrial[i][ j] );Map.m_dDeltTrial[i][j]=0;}}}void project::initmap(){int i;int j;for(i=0;i〈iCityCount;i++)for (j=0;j〈iCityCount;j++){Map.m_dTrial[i][j]=1;Map.m_dDeltTrial[i][j]=0;}}project::project(){//initial map,read map infomation from file . et.initmap();m_dLength=10e9;ifstream in("eil51.tsp");struct city{int num;int x;int y;}cc[iCityCount];for (int i=0;i〈iCityCount;i++){in>>cc[i].num>>cc[i].x>>cc[i].y;besttour[i]=0;}int j;for(i=0;i〈iCityCount;i++)for (j=0;j〈iCityCount;j++){{Map.distance[i][j]=sqrt(pow((cc[i].x-cc[j].x),2)+pow((cc[i].y -cc[j].y),2));}}}void project::GetAnt(){//randomly put ant into mapint i=0;int city;srand( (unsigned)time( NULL ) +rand());for (i=0;i〈iAntCount;i++){city=rnd(iCityCount);ants[i].addcity(city);}}void project::StartSearch(){//begin to find best solutionint max=0;//every ant tours timesint i;int j;double temp;int temptour[iCityCount];while ((max〈iItCount){for(j=0;j〈iAntCount;j++){for (i=0;i〈iCityCount-1;i++)ants[j].move();}for(j=0;j〈iAntCount;j++){ ants[j].move2last();ants[j].UpdateResult ();}//find out the best solution of the step and put it in to tempint t;temp=ants[0].m_dLength;for (t=0;t〈iCityCount;t++)temptour[t]=ants[0].tabu[t];for(j=0;j〈iAntCount;j++){if (temp〉ants[j].m_dLength) {temp=ants[j].m_dLength;for ( t=0;t〈iCityCount;t++)temptour[t]=ants[j].tabu[t];}}if(temp〈m_dLength){m_dLength=temp;for ( t=0;t〈iCityCount;t++)besttour[t]=temptour[t];}printf("%d : %f\n",max,m_dLength);UpdateTrial();for(j=0;j〈iAntCount;j++)ants[j].Clear();max++;}printf("The shortest toure is : %f\n",m_dLength);for ( int t=0;t〈iCityCount;t++)printf(" %d ",besttour[t]);}int main(){project TSP;TSP.GetAnt();TSP.StartSearch();return 0;}求eil51最优到了438,可以修改循环次数和其他参数。