蚁群算法c语言

合集下载

c++蚁群算法最短路径代码

c++蚁群算法最短路径代码
if (temp) {
temp=pow((1.0/Map.distance[curCity][i]),beta)*pow((Map.m_dTrial[curCity][i]),alpha);
j=i;
}
}
}
return j;
}
ant::ant()
double sel=0;
for (i=0;i<iCityCount;i++)
{
if(Map.distance[curCity][i]&&(AllowedCity[i]==1))
{
prob[i]=pow((1.0/Map.distance[curCity][i]),beta)*pow((Map.m_dTrial[curCity][i]),alpha)/temp;
int i;
for(i=0;tabu[i]!=iCityCount-1;i++)
m_dLength+=Map.distance[tabu[i]][tabu[i+1]];
}
int ant::move()
{
//the ant move to next town and add town ID to tabu.
{
for (j=0;ants[i].tabu[j]!=iCityCount-1&&rValue[j]!=-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;

蚂蚁算法

蚂蚁算法

蚂蚁算法求解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)的物质相互传递信息。

更具体地,蚂蚁在运动过程中能够在其所经过的路径上留下信息素,而且在运动过程中能够感受到这种信息素的存在及其强度,并以此指导自己的运动方向。

蚂蚁倾向于朝着信息素浓度高的方向前进,因此,由大量蚂蚁组成的蚁群的行为便表现出一种信息的正反馈现象:某一路径上走过的蚂蚁越多,则后来者选择该路径的概率就越大。

蚁群算法附带数据结果

蚁群算法附带数据结果

[代码说明]蚁群算法解决VRP问题[算法说明]首先实现一个ant蚂蚁类,用此蚂蚁类实现搜索。

算法按照tsp问题去解决,但是在最后计算路径的时候有区别。

比如有10个城市,城市1是配送站,蚂蚁搜索的得到的路径是1,3,5,9,4,10,2,6,8,7。

计算路径的时候把城市依次放入派送线路中,每放入一个城市前,检查该城市放入后是否会超过车辆最大载重如果没有超过就放入如果超过,就重新开始一条派送路线……直到最后一个城市放完就会得到多条派送路线这样处理比较简单可以把vrp问题转为tsp问题求解但是实际效果还需要验证。

[作者]Wugsh@2011.12.16wuguangsheng@guangsheng.wu@%}%清除所有变量和类的定义clear;clear classes;%蚁群算法参数(全局变量)global ALPHA; %启发因子global BETA; %期望因子global ANT_COUNT; %蚂蚁数量global CITY_COUNT; %城市数量global RHO; %信息素残留系数!!!global IT_COUNT; %迭代次数global DAry; %两两城市间距离global TAry; %两两城市间信息素global CITYW Ary; %城市货物需求量global VW; %车辆最大载重%===================================================================%设置参数变量值ALPHA=1.0;BETA=2.0;RHO=0.95;IT_COUNT=200;VW=100;%=================================================================== %读取数据并根据读取的数据设置其他参数load data.txt; %从文本文件加载数据city_xy_ary=data(:,2:3); %得到城市的坐标数据CITYW Ary=data(:,4); %得到每个城市的货物需求量CITY_COUNT=length(CITYW Ary); %得到城市数量(包括配送站在内)ANT_COUNT=round(CITY_COUNT*2/3)+1; %根据城市数量设置蚂蚁数量,一般设置为城市数量的2/3%MMAS信息素参数%计算最大信息素和最小信息素之间的比值PBest=0.05; %蚂蚁一次搜索找到最优解的概率temp=PBest^(1/CITY_COUNT);TRate=(1-temp)/((CITY_COUNT/2-1)*temp); %最大信息素和最小信息素之间的比值%信息素的最大最小值开始的时候设置成多大无所谓%第一次搜索完成会生成一个最优解,然后用这个解会重新产生最大最小值Tmax=1; %信息素最大值Tmin=Tmax*TRate; %信息素最小值% 计算两两城市间距离DAry=zeros(CITY_COUNT);for i=1:CITY_COUNTfor j=1:CITY_COUNTDAry(i,j)=sqrt((city_xy_ary(i,1)-city_xy_ary(j,1))^2+(city_xy_ary(i,2)-city_xy_ary(j,2))^2);endend% 初始化城市间信息素TAry=zeros(CITY_COUNT);TAry=TAry+Tmax;%===================================================================%初始化随机种子rand('state', sum(100*clock));%另一种方法%rand('twister',sum(100*clock))%定义蚂蚁mayi=ant();Best_Path_Length=10e9; %最佳路径长度,先设置成一个很大的值tm1=datenum(clock); %记录算法开始执行时的时间FoundBetter=0; %一次搜索是否有更优解产生%开始搜索for i=1:IT_COUNTfprintf('开始第%d次搜索, 剩余%d次',i,IT_COUNT-i);FoundBetter=0; %搜索前先置为没有更优解产生for j=1:ANT_COUNT%蚂蚁搜索一次mayi=Search(mayi);%得到蚂蚁搜索路径长度Length_Ary(j)=get(mayi,'path_length');%得到蚂蚁搜索的路径Path_Ary{j}=get(mayi,'path');%保存最优解if (Length_Ary(j) < Best_Path_Length);Best_Path_Length=Length_Ary(j);Best_Path=Path_Ary{j};%有更优解产生,设置标志FoundBetter=1;endend%有更好解产生,进行2-OPT优化if (FoundBetter == 1)fprintf(' , 本次搜索找到更好解!');Best_Path=opt2(Best_Path);Best_Path_Length=PathLength(Best_Path);end%-------------------------------------------------------------%全部蚂蚁搜索完一次,更新环境信息素TAry=TAry*RHO;%只有全局最优蚂蚁释放信息素dbQ=1/Best_Path_Length;for k=2:CITY_COUNTm=Best_Path(k-1); %上一个城市编号n=Best_Path(k); %下一个城市编号%更新路径上的信息素TAry(m,n)=TAry(m,n)+dbQ;TAry(n,m)=TAry(m,n);end%更新最后城市返回出发城市路径上的信息素TAry(n,1)=TAry(n,1)+dbQ;TAry(1,n)=TAry(n,1);%-------------------------------------------------------------%更新完信息素,进行边界检查Tmax=1/((1-RHO)*Best_Path_Length); %信息素最大值Tmin=Tmax*TRate; %信息素最小值for m=1:CITY_COUNTfor n=1:CITY_COUNTif (TAry(m,n)>Tmax)TAry(m,n)=Tmax;endif (TAry(m,n)<Tmin)TAry(m,n)=Tmin;endendend%-------------------------------------------------------------%换行fprintf('\n');endtm2=datenum(clock); %记录算法结束执行时的时间fprintf('\n搜索完成, 用时%.3f秒, 最佳路径长为%.3f , 派送方案如下::\n\n[1]',(tm2-tm1)*86400,Best_Path_Length);%=================================================================== %输出结果dbW=0;for i=2:CITY_COUNTm=Best_Path(i-1); %上一个城市n=Best_Path(i); %当前城市if (dbW+CITYW Ary(n)>VW) %运送的货物超过限制fprintf(' (满载率: %.1f%%)\n[1]-%d',dbW*100/VW,n);dbW=CITYW Ary(n); %运输的重量等于该城市的需求量else %没有超过限制fprintf('-%d',n);dbW=dbW+CITYWAry(n); %运输的重量加上该城市的需求量endendfprintf(' (满载率: %.1f%%)',dbW*100/VW);fprintf('\n\n');%====== [程序结束]===================================================== %对结果进行2-OPT优化function f=opt2(Line)%数组长度size=length(Line);NewLine=Line; % 返回结果先设置成原来路径Flag=1;while (Flag == 1)Flag=0;for i=1:size-2a=Line(1,1:i); %路径前段b=fliplr(Line(1,i+1:size)); %路径后段倒置c=cat(2,a,b); %新路径%新路径更好就替换if (PathLength(c)<PathLength(NewLine))NewLine=c;Flag=1;fprintf('\n======================= 2-OPT 优化成功! ===');endendend%返回结果f=NewLine;end1 14.5 13.0 0.02 12.8 8.5 0.13 18.4 3.4 0.44 15.4 16.6 1.25 18.9 15.2 1.56 15.5 11.6 0.87 3.9 10.6 1.38 10.6 7.6 1.79 8.6 8.4 0.610 12.5 2.1 1.211 13.8 5.2 0.412 6.7 16.9 0.913 14.8 2.6 1.314 1.8 8.7 1.315 17.1 11.0 1.916 7.4 1.0 1.717 0.2 2.8 1.118 11.9 19.8 1.519 13.2 15.1 1.620 6.4 5.6 1.721 9.6 14.8 1.51 0 0 02 3639 1315 123 4177 2244 134 3712 1399 145 3488 1535 536 3326 1556 457 3238 1229 228 4196 1004 119 4312 790 1110 4386 570 5611 3007 1970 4312 2562 1756 2413 2788 1491 6514 2381 1676 3215 1332 695 5616 3715 1678 6717 3918 2179 6718 4061 2370 2219 3780 2212 3420 3676 2578 5621 4029 2838 2422 4263 2931 2523 3429 1908 2624 3507 2367 4625 3394 2643 8726 3439 3201 3327 2935 3240 2228 3140 3550 2429 2545 2357 5630 2778 2826 2431 2370 2975 4332 1304 2312 12。

蚁群算法——精选推荐

蚁群算法——精选推荐

蚁群算法⼀、蚁群算法蚁群算法是在20世纪90年代由澳⼤利亚学者Marco Dorigo等⼈通过观察蚁群觅⾷的过程,发现众多蚂蚁在寻找⾷物的过程中,总能找到⼀条从蚂蚁巢⽳到⾷物源之间的最短路径。

随后他们在蚂蚁巢⽳到⾷物源之间设置了⼀个障碍,⼀段时间以后发现蚂蚁⼜重新⾛出了⼀条到⾷物源最短的路径。

通过对这种现象的不断研究,最后提出了蚁群算法。

蚁群算法在解决(即TSP问题)时,取得了⽐较理想的结果。

⼆、基本⼈⼯蚁群算法原理运⽤⼈⼯蚁群算法求解TSP问题时的基本原理是:将m个蚂蚁随机地放在多个城市,让这些蚂蚁从所在的城市出发,n步(⼀个蚂蚁从⼀个城市到另外⼀个城市为1步)之后返回到出发的城市。

如果m个蚂蚁所⾛出的m条路经对应的中最短者不是TSP问题的最短路程,则重复这⼀过程,直⾄寻找到满意的TSP问题的最短路径为⽌。

为了说明这⼀个算法下⾯⽤⼀个算法流程图来表⽰⼀下:三、蚁群算法中涉及到的参数及其符号::蚂蚁数量,约为城市数量的1.5倍。

如果蚂蚁数量过⼤,则每条路径上的信息素浓度趋于平均,正反馈作⽤减弱,从⽽导致收敛速度减慢;如果过⼩,则可能导致⼀些从未搜索过的路径信息素浓度减⼩为0,导致过早收敛,解的全局最优性降低:信息素因⼦,反映了蚂蚁运动过程中积累的信息量在指导蚁群搜索中的相对重要程度,取值范围通常在[1, 4]之间。

如果信息素因⼦值设置过⼤,则容易使随机搜索性减弱;其值过⼩容易过早陷⼊局部最优:启发函数因⼦,反映了启发式信息在指导蚁群搜索中的相对重要程度,取值范围在[3, 4.5]之间。

如果值设置过⼤,虽然收敛速度加快,但是易陷⼊局部最优;其值过⼩,蚁群易陷⼊纯粹的随机搜索,很难找到最优解:信息素挥发因⼦,反映了信息素的消失⽔平,相反的反映了信息素的保持⽔平,取值范围通常在[0.2, 0.5]之间。

当取值过⼤时,容易影响随机性和全局最优性;反之,收敛速度降低:信息素常数,表⽰蚂蚁遍历⼀次所有城市所释放的信息素总量。

C#实现蚁群算法

C#实现蚁群算法

/sun_raining61/blog/item/449da9240b1e71024d088d5d.html/cmtid/1056b bed39d4d24779f05502using System;using System.Collections.Generic;using System.Text;namespace AntSystem{public class AA{/**//// <summary>/// 对信息量的重视程度/// </summary>private int alpha;/**//// <summary>/// 启发式信息的受重视程度/// </summary>private int beta;/**//// <summary>/// 信息素的挥发速度/// </summary>private double lo;/**//// <summary>/// 城市距离矩阵/// </summary>private double[,] City;/**//// <summary>/// 信息素矩阵/// </summary>private double[,] Message;/**//// <summary>/// opneList用于存放下一步可行城市/// </summary>private Queue<int> openList=new Queue<int> ();/**//// <summary>/// closedList用于存放已经访问过的城市/// </summary>private Queue<int> closedList=new Queue<int> ();/**//// <summary>/// 储存较好的路径/// </summary>private Queue <int> BestList=new Queue<int> ();private int Pro_time = 0;/**///////////////////////////////////////////////////////////// <summary>/// 构造函数:形成城市距离和信息素矩阵/// </summary>/// <param name="city">城市距离矩阵</param>/// <param name="Lo"> 信息素的挥发速度</param> public AA(double[,] city,double Lo,int Alpha,int Beta) {alpha = Alpha;beta = Beta;lo=Lo;int temp = Convert.ToInt32( Math.Sqrt(city.Length)); City=new double [temp,temp];Message=new double [temp,temp];for (int i = 0; i < temp; i++){for (int j = 0; j < temp; j++){City[i, j] = city[i, j];}}//初始化信息素矩阵for (int i = 0; i < temp; i++){for (int j = 0; j < temp; j++){if (i != j){Message[i, j] = (double)1 / (temp * temp - temp);}}}}/**//////////////////////////////////////////////////////////////// <summary>/// 改变信息素矩阵,closed_list为较好的路径/// </summary>/// <param name="closed_list"></param>private void Change_Message(Queue<int> closed_list) {lock (this){int[] temp_Array = new int[closed_list.Count];temp_Array = closed_list.ToArray();for (int i = 0; i < closed_list.Count - 1; i++){Message[temp_Array[i], temp_Array[i + 1]] = Message[temp_Array[i], temp_Array[i + 1]] + lo / ((1 - lo) *Convert.ToInt32(Get_Weight(closed_list)+1));}Message[temp_Array[temp_Array.Length - 1], temp_Array[0]] = Message[temp_Array[temp_Array.Length - 1], temp_Array[0]] + lo / ((1 - lo) *Convert.ToInt32(Get_Weight(closed_list)));for (int i = 0; i < closed_list.Count; i++){for (int j = 0; j < closed_list.Count; j++){Message[i, j] = (1 - lo) * Message[i, j];}}}}/**/////////////////////////////////////////////////////////////////// <summary>/// 输入一个链表,计算出其对应的总路径/// </summary>/// <param name="closed_list"></param>/// <returns></returns>public double Get_Weight(Queue <int> closed_list){lock (this){double sum = 0;int[] temp_Array = new int[closed_list.Count];temp_Array = closed_list.ToArray();for (int i = 0; i < Convert.ToInt32(temp_Array.Length) - 1; i++){sum = sum + City[temp_Array[i], temp_Array[i + 1]];}sum = sum + City[temp_Array[temp_Array.Length - 1], temp_Array[0]];return sum;}}/**////////////////////////////////////////////////////////////////// <summary>/// 产生到i城市后,下一个可走城市的集合。

蚁群算法——精选推荐

蚁群算法——精选推荐

蚁群算法⼀、蚁群算法简介 蚁群算法(AG)是⼀种模拟蚂蚁觅⾷⾏为的模拟优化算法,它是由意⼤利学者Dorigo M等⼈于1991年⾸先提出,并⾸先使⽤在解决TSP(旅⾏商问题)上。

之后,⼜系统研究了蚁群算法的基本原理和数学模型.⼆、蚁群算法原理1、蚂蚁在路径上释放信息素。

2、碰到还没⾛过的路⼝,就随机挑选⼀条路⾛。

同时,释放与路径长度有关的信息素。

3、信息素浓度与路径长度成反⽐。

后来的蚂蚁再次碰到该路⼝时,就选择信息素浓度较⾼路径。

4、最优路径上的信息素浓度越来越⼤。

5、最终蚁群找到最优寻⾷路径。

三、蚁群算法流程图四、实例应⽤基于TSP问题的基本蚁群算法原理讲解参考⽼师上课讲解的PPT不做过多粘贴1.源代码:%% 旅⾏商问题(TSP)优化%% 清空环境变量clear allclc%% 导⼊数据citys = ceil(rand(50,2)*50000)%load newcitys.mat%% 计算城市间相互距离fprintf('Computing Distance Matrix... \n');n = size(citys,1);D = zeros(n,n);for i = 1:nfor j = 1:nif i ~= jD(i,j) = sqrt(sum((citys(i,:) - citys(j,:)).^2));elseD(i,j) = 1e-4;endendend%% 初始化参数fprintf('Initializing Parameters... \n');m = 50; % 蚂蚁数量alpha = 1; % 信息素重要程度因⼦beta = 5; % 启发函数重要程度因⼦rho = 0.05; % 信息素挥发因⼦Q = 1; % 常系数Eta = 1./D; % 启发函数Tau = ones(n,n); % 信息素矩阵Table = zeros(m,n); % 路径记录表iter = 1; % 迭代次数初值iter_max = 150; % 最⼤迭代次数Route_best = zeros(iter_max,n); % 各代最佳路径Length_best = zeros(iter_max,1); % 各代最佳路径的长度Length_ave = zeros(iter_max,1); % 各代路径的平均长度%% 迭代寻找最佳路径figure;while iter <= iter_maxfprintf('迭代第%d次\n',iter);% 随机产⽣各个蚂蚁的起点城市start = zeros(m,1);for i = 1:mtemp = randperm(n);start(i) = temp(1);endTable(:,1) = start;% 构建解空间citys_index = 1:n;% 逐个蚂蚁路径选择for i = 1:m% 逐个城市路径选择for j = 2:ntabu = Table(i,1:(j - 1)); % 已访问的城市集合(禁忌表)allow_index = ~ismember(citys_index,tabu);allow = citys_index(allow_index); % 待访问的城市集合P = allow;% 计算城市间转移概率for k = 1:length(allow)P(k) = Tau(tabu(end),allow(k))^alpha * Eta(tabu(end),allow(k))^beta; endP = P/sum(P);% 轮盘赌法选择下⼀个访问城市Pc = cumsum(P);target_index = find(Pc >= rand);target = allow(target_index(1));Table(i,j) = target;endend% 计算各个蚂蚁的路径距离Length = zeros(m,1);for i = 1:mRoute = Table(i,:);for j = 1:(n - 1)Length(i) = Length(i) + D(Route(j),Route(j + 1));endLength(i) = Length(i) + D(Route(n),Route(1));end% 计算最短路径距离及平均距离if iter == 1[min_Length,min_index] = min(Length);Length_best(iter) = min_Length;Length_ave(iter) = mean(Length);Route_best(iter,:) = Table(min_index,:);else[min_Length,min_index] = min(Length);Length_best(iter) = min(Length_best(iter - 1),min_Length);Length_ave(iter) = mean(Length);if Length_best(iter) == min_LengthRoute_best(iter,:) = Table(min_index,:);elseRoute_best(iter,:) = Route_best((iter-1),:);endend% 更新信息素Delta_Tau = zeros(n,n);% 逐个蚂蚁计算for i = 1:m% 逐个城市计算for j = 1:(n - 1)Delta_Tau(Table(i,j),Table(i,j+1)) = Delta_Tau(Table(i,j),Table(i,j+1)) + Q/Length(i); endDelta_Tau(Table(i,n),Table(i,1)) = Delta_Tau(Table(i,n),Table(i,1)) + Q/Length(i); endTau = (1-rho) * Tau + Delta_Tau;% 迭代次数加1,清空路径记录表% figure;%最佳路径的迭代变化过程[Shortest_Length,index] = min(Length_best(1:iter));Shortest_Route = Route_best(index,:);plot([citys(Shortest_Route,1);citys(Shortest_Route(1),1)],...[citys(Shortest_Route,2);citys(Shortest_Route(1),2)],'o-');pause(0.3);iter = iter + 1;Table = zeros(m,n);% endend%% 结果显⽰[Shortest_Length,index] = min(Length_best);Shortest_Route = Route_best(index,:);disp(['最短距离:' num2str(Shortest_Length)]);disp(['最短路径:' num2str([Shortest_Route Shortest_Route(1)])]);%% 绘图figure(1)plot([citys(Shortest_Route,1);citys(Shortest_Route(1),1)],...[citys(Shortest_Route,2);citys(Shortest_Route(1),2)],'o-');grid onfor i = 1:size(citys,1)text(citys(i,1),citys(i,2),[' ' num2str(i)]);endtext(citys(Shortest_Route(1),1),citys(Shortest_Route(1),2),' 起点');text(citys(Shortest_Route(end),1),citys(Shortest_Route(end),2),' 终点');xlabel('城市位置横坐标')ylabel('城市位置纵坐标')title(['蚁群算法优化路径(最短距离:' num2str(Shortest_Length) ')'])figure(2)plot(1:iter_max,Length_best,'b',1:iter_max,Length_ave,'r:')legend('最短距离','平均距离')xlabel('迭代次数')ylabel('距离')title('各代最短距离与平均距离对⽐')运⾏结果:利⽤函数citys = ceil(rand(50,2)*50000) 随机产⽣五⼗个城市坐标2.研究信息素重要程度因⼦alpha, 启发函数重要程度因⼦beta,信息素挥发因⼦rho对结果的影响为了保证变量唯⼀我重新设置五⼗个城市信息进⾏实验在原来设值运⾏结果:实验结果可知当迭代到120次趋于稳定2.1 alpha值对实验结果影响(1)当alpha=4时运⾏结果实验结果可知当迭代到48次左右趋于稳定(2)当alpha=8时运⾏结果:有图可知迭代40次左右趋于稳定,搜索性较⼩(3)当alpha= 0.5运⾏结果:有图可知迭代到140次左右趋于稳定(4)当alpha=0.2时运⾏结果:结果趋于110次左右稳定所以如果信息素因⼦值设置过⼤,则容易使随机搜索性减弱;其值过⼩容易过早陷⼊局部最优2.2 beta值对实验影响(1)当 beta=8时运⾏结果结果迭代75次左右趋于稳定(2)当 beta=1时运⾏结果:结果迭代130次左右趋于稳定所以beta如果值设置过⼤,虽然收敛速度加快,但是易陷⼊局部最优;其值过⼩,蚁群易陷⼊纯粹的随机搜索,很难找到最优解2.3 rho值对实验结果影响(1)当rho=3时运⾏结果:结果迭代75次左右趋于稳定(2)当rho=0.05运⾏结果:结果迭代125次左右趋于稳定所以如果rho取值过⼤时,容易影响随机性和全局最优性;反之,收敛速度降低总结:蚁群算法对于参数的敏感程度较⾼,参数设置的好,算法的结果也就好,参数设置的不好则运⾏结果也就不好,所以通常得到的只是局部最优解。

蚁群算法求解最小点覆盖问题

蚁群算法求解最小点覆盖问题

蚁群算法求解最小点覆盖问题蚁群算法求解最小点覆盖问题蚁群算法是一种基于自然界中蚂蚁觅食行为的启发式搜索算法,其基本原理是通过模拟蚂蚁的觅食路径选择行为,从而找到问题的最优解。

最小点覆盖问题是计算机科学中的一个重要问题,其目标是找到能够覆盖所有边的最小点集合。

在蚁群算法中,一群蚂蚁以随机的方式在问题空间中搜索解空间。

在最小点覆盖问题中,解空间由所有可能的点集合组成。

每只蚂蚁通过释放信息素的方式与其他蚂蚁进行信息交流,并根据信息素的浓度选择下一个点。

蚂蚁在搜索空间中的移动行为可以用概率模型来表示。

每只蚂蚁在选择下一个点时,会根据该点的信息素浓度和启发式函数的值计算出一个概率,概率越大,选择该点的可能性就越高。

启发式函数可以根据问题的特性进行设计,以引导蚂蚁向着更有可能获得更优解的方向移动。

当蚂蚁选择好下一个点后,会在当前选择的点上释放一定量的信息素。

信息素的释放量取决于该点是否能够覆盖边,如果能够覆盖,则释放的信息素量更大;反之,则释放的信息素量较小。

通过这种方式,好的解对应的点将会得到更多的信息素,从而引导其他蚂蚁更有可能选择该点。

在蚁群算法中,信息素的更新和蒸发也是一个重要的步骤。

信息素的更新根据蚂蚁选择的路径以及路径的覆盖情况来进行,覆盖边多的路径将会释放更多的信息素。

而信息素的蒸发则是为了防止信息素过度积累,通过蒸发可以降低信息素浓度,使得蚂蚁在搜索空间中具有更好的探索能力。

通过多轮的迭代搜索,蚂蚁群体会逐渐收敛到最优解。

每次迭代结束后,根据蚂蚁选择的路径对问题进行评估,选择具有最小点数的解作为当前的最优解。

并且根据当前的最优解来更新全局最优解。

这个过程一直持续到满足停止条件为止。

蚁群算法作为一种启发式搜索算法,具有自适应性和自学习的优势。

它能够通过信息素的引导来全局搜索解空间,并在搜索过程中不断调整搜索策略,逐渐找到更优的解。

同时,在处理最小点覆盖问题时,蚁群算法还可以考虑到局部信息和全局信息的平衡,以及避免过早陷入局部最优解。

蚁群算法——精选推荐

蚁群算法——精选推荐

蚁群算法蚁群算法⽬录1 蚁群算法基本思想 (1)1.1蚁群算法简介 (1)1.2蚁群⾏为分析 (1)1.3蚁群算法解决优化问题的基本思想 (2)1.4蚁群算法的特点 (2)2 蚁群算法解决TSP问题 (3)2.1关于TSP (3)2.2蚁群算法解决TSP问题基本原理 (3)2.3蚁群算法解决TSP问题基本步骤 (5)3 案例 (6)3.1问题描述 (6)3.2解题思路及步骤 (6)3.3MATLB程序实现 (7)3.1.1 清空环境 (7)3.2.2 导⼊数据 (7)3.3.3 计算城市间相互距离 (7)3.3.4 初始化参数 (7)3.3.5 迭代寻找最佳路径 (7)3.3.6 结果显⽰ (7)3.3.7 绘图 (7)1 蚁群算法基本思想1.1 蚁群算法简介蚁群算法(ant colony algrothrim,ACA)是由意⼤利学者多⾥⼽(Dorigo M)、马聂佐(Maniezzo V )等⼈于20世纪90初从⽣物进化的机制中受到启发,通过模拟⾃然界蚂蚁搜索路径的⾏为,提出来的⼀种新型的模拟进化算法。

该算法⽤蚁群在搜索⾷物源的过程中所体现出来的寻优能⼒来解决⼀些系统优化中的困难问题,其算法的基本思想是模仿蚂蚁依赖信息素,通过蚂蚁间正反馈的⽅法来引导每个蚂蚁的⾏动。

蚁群算法能够被⽤于解决⼤多数优化问题或者能够转化为优化求解的问题,现在其应⽤领域已扩展到多⽬标优化、数据分类、数据聚类、模式识别、电信QoS管理、⽣物系统建模、流程规划、信号处理、机器⼈控制、决策⽀持以及仿真和系统辩识等⽅⾯。

蚁群算法是群智能理论研究领域的⼀种主要算法。

1.2 蚁群⾏为分析Bm=20t=0 m=10m=10t=11.3 蚁群算法解决优化问题的基本思想⽤蚂蚁的⾏⾛路径表⽰待优化问题的可⾏解,整个蚂蚁群体的所有路径构成待优化问题的解空间。

路径较短的蚂蚁释放的信息量较多,随着时间的推进,较短路径上积累的信息浓度逐渐增⾼,选择该路径的蚂蚁个数愈来愈多。

蚁群算法详细讲解

蚁群算法详细讲解

21
1.2 蚁群优化算法概念
1.2.1 蚁群算法原理 1.2.2 简化的蚂蚁寻食过程 1.2.3 自然蚁群与人工蚁群算法 1.2.4 蚁群算法与TSP问题 1.2.5 初始的蚁群优化算法—基于图的 蚁群系统(GBAS) 1.2.6 一般蚁群算法的框架
22
1.2.1 蚁群算法原理
蚁群算法是对自然界蚂蚁的寻径方式进行模似而得出的一种仿 生算法。蚂蚁在运动过程中,能够在它所经过的路径上留下一种称 之为外激素(pheromone)的物质进行信息传递,而且蚂蚁在运动过 程中能够感知这种物质,并以此指导自己的运动方向,因此由大量 蚂蚁组成的蚁群集体行为便表现出一种信息正反馈现象:某一路径 上走过的蚂蚁越多,则后来者选择该路径的概率就越大。 为了说明蚁群算法的原理,先简要介绍一下蚂蚁搜寻食物的具 体过程。在蚁群寻找食物时,它们总能找到一条从食物到巢穴之间 的最优路径。这是因为蚂蚁在寻找路径时会在路径上释放出一种特 殊的信息素。当它们碰到一个还没有走过的路口时.就随机地挑选 一条路径前行。与此同时释放出与路径长度有关的信息素。路径越 长,释放的激索浓度越低.当后来的蚂蚁再次碰到这个路口的时 候.选择激素浓度较高路径概率就会相对较大。这样形成一个正反 馈。最优路径上的激索浓度越来越大.而其它的路径上激素浓度却 会随着时间的流逝而消减。最终整个蚁群会找出最优路径。
23
1.2.2 简化的蚂蚁寻食过程 1/3
蚂蚁从A点出发,速度相同,食物在D点,可能随机选择路线ABD 或ACD。假设初始时每条分配路线一只蚂蚁,每个时间单位行走 一步,本图为经过9个时间单位时的情形:走ABD的蚂蚁到达终点, 而走ACD的蚂蚁刚好走到C点,为一半路程。
17
1.1.5 蚁群优化算法应用现状 2/5

蚁群算法C

蚁群算法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//会出现经过上述操作,没有城市被选择出来//出现这种情况,就把第一个没去过的城市作为返回结果//题外话:刚开始看的时候,下面这段代码困惑了我很长时间,想不通为何要有这段代码,后来才搞清楚。

蚁群算法概念

蚁群算法概念

蚁群算法概念
蚁群算法(Ant Colony Algorithm,ACA)是一种模拟蚁群觅食行为的启发式优化算法,被广泛应用于求解组合优化问题。

其基本思想是通过多个“蚂蚁”在问题的解空间中搜索最优解,并通过互相交流信息来引导搜索过程。

蚂蚁在搜索过程中通过携带的信息素标记路径,信息素浓度表示路径的好坏程度。

路径上的信息素浓度增加与蚂蚁对路径的评价正相关,蚂蚁根据信息素浓度的大小选择下一步的移动方向。

同时,信息素会随着时间的推移逐渐挥发,从而模拟蚁群搜索过程中信息的传递与更新。

蚁群算法的主要步骤包括初始化信息素、蚂蚁的移动、更新信息素以及重复执行这些步骤。

通过多次迭代,蚁群算法能够逐步搜索到问题的最优解。

蚁群算法具有全局优化能力和强鲁棒性,在解决复杂优化问题和组合优化问题方面具有较高的效果和应用价值。

它在路线规划、物流配送、旅行商问题等领域都有广泛的应用。

23个基本测试函数 蚁群算法

23个基本测试函数 蚁群算法

23个基本测试函数蚁群算法蚁群算法是一种模拟蚂蚁行为的启发式算法,它通过模拟蚁群寻找食物的行为,来解决各种优化问题。

蚁群算法的核心思想是通过信息交流和反馈机制来寻找问题的最优解。

本文将介绍蚁群算法的基本原理,并以23个基本测试函数为例,展示蚁群算法在解决优化问题中的应用。

1. 算法简介蚁群算法最早由意大利学者Dorigo在1992年提出,其灵感来自于观察蚂蚁在寻找食物时的行为。

蚁群算法将问题抽象成一个图论模型,其中蚂蚁代表解空间中的候选解,信息素则代表蚂蚁之间的信息交流。

蚂蚁根据信息素的浓度和距离选择路径,并在路径上释放信息素,从而影响其他蚂蚁的选择。

通过多次迭代,蚂蚁群体逐渐收敛于最优解。

2. 蚁群算法的基本步骤蚁群算法主要包括初始化、路径选择、信息素更新和收敛判断等步骤。

2.1 初始化在蚁群算法中,需要初始化蚂蚁的位置和信息素的浓度。

蚂蚁的初始位置可以随机选择或者根据问题的特点进行设置。

信息素的初始浓度通常设置为一个较小的常数。

2.2 路径选择在路径选择阶段,蚂蚁根据信息素的浓度和距离选择路径。

通常情况下,信息素浓度较高的路径会有更多的蚂蚁选择,但也存在一定的随机性,以保证算法能够全局搜索。

2.3 信息素更新在信息素更新阶段,蚂蚁根据问题的优化目标更新路径上的信息素。

通常情况下,蚂蚁在路径上释放的信息素与路径的优化程度成正比。

信息素的更新规则可以根据具体问题进行设计。

2.4 收敛判断在每轮迭代之后,需要判断算法是否收敛。

通常情况下,可以通过设定一个停止准则来判断算法是否继续迭代。

常用的停止准则包括迭代次数、目标函数值的变化幅度等。

3. 蚁群算法在优化问题中的应用蚁群算法在解决各种优化问题中具有广泛的应用。

下面以23个基本测试函数为例,展示蚁群算法在不同问题中的应用。

3.1 球面函数球面函数是一个简单的优化问题,目标是找到一个全局最小值。

蚁群算法通过信息素的交流和反馈机制,可以在搜索空间中快速找到最优解。

蚁群算法代码

蚁群算法代码

算法解释:程序开始运行,蚂蚁们开始从窝里出动了,寻找食物;他们会顺着屏幕爬满整个画面,直到找到食物再返回窝。

其中,‘F’点表示食物,‘H’表示窝,白色块表示障碍物,‘+’就是蚂蚁了。

预期的结果:各个蚂蚁在没有事先告诉他们食物在什么地方的前提下开始寻找食物。

当一只找到食物以后,它会向环境释放一种信息素,吸引其他的蚂蚁过来,这样越来越多的蚂蚁会找到食物!有些蚂蚁并没有象其它蚂蚁一样总重复同样的路,他们会另辟蹊径,如果令开辟的道路比原来的其他道路更短,那么,渐渐,更多的蚂蚁被吸引到这条较短的路上来。

最后,经过一段时间运行,可能会出现一条最短的路径被大多数蚂蚁重复着。

原理:为什么小小的蚂蚁能够找到食物?他们具有智能么?设想,如果我们要为蚂蚁设计一个人工智能的程序,那么这个程序要多么复杂呢?首先,你要让蚂蚁能够避开障碍物,就必须根据适当的地形给它编进指令让他们能够巧妙的避开障碍物,其次,要让蚂蚁找到食物,就需要让他们遍历空间上的所有点;再次,如果要让蚂蚁找到最短的路径,那么需要计算所有可能的路径并且比较它们的大小,而且更重要的是,你要小心翼翼的编程,因为程序的错误也许会让你前功尽弃。

这是多么不可思议的程序!太复杂了,恐怕没人能够完成这样繁琐冗余的程序。

然而,事实并没有你想得那么复杂,上面这个程序每个蚂蚁的核心程序编码不过100多行!为什么这么简单的程序会让蚂蚁干这样复杂的事情?答案是:简单规则的涌现。

事实上,每只蚂蚁并不是像我们想象的需要知道整个世界的信息,他们其实只关心很小范围内的眼前信息,而且根据这些局部信息利用几条简单的规则进行决策,这样,在蚁群这个集体里,复杂性的行为就会凸现出来。

这就是人工生命、复杂性科学解释的规律!那么,这些简单规则是什么呢?下面详细说明:1、范围:蚂蚁观察到的范围是一个方格世界,蚂蚁有一个参数为速度半径(一般是3),那么它能观察到的范围就是3*3个方格世界,并且能移动的距离也在这个范围之内。

蚁群算法

蚁群算法

蚁群算法Ant Colony Algorithms真实世界的蚂蚁行为真实世界的蚂蚁行为即使两条路径一样长,蚂蚁也会强化对其中一条的选择(收敛性)蚁群算法(Ant Algorithms)蚂蚁几乎是没有视力的,它们是如何找到食物和家之间的路径的?在觅食过程中,蚂蚁在它所经过的路径上留下浓度与食物源质量成比例的信息素(pheromone) ,并能够感知信息素的存在及其浓度,以此指导自己的运动方向,倾向于朝着信息素浓度高的方向移动.蚁群算法(Ant Algorithms)于是,蚁群的集体行为便表现出一种信息正反馈现象:某一路径上走过的蚂蚁越多,则后来者选择该路径的概率就越大,因此质量好、距离近的食物源会吸引越来越多的蚂蚁,信息素浓度的增长速度会更快. 蚂蚁个体之间就是通过这种信息的交流达到寻找食物和蚁穴之间最短路径的目的蚁群算法(d=1d=1A蚁群算法(Ant Algorithms)我们感兴趣的是对解空间的探索,而非简单的数路径; 应允许蚂蚁们以概率的方式选择路径以及确定最佳路径,概率与信息素的浓度成比例。

不希望蚂蚁们简单地根据最高浓度来选择路径,如果这样的话,搜索会迅速地陷入局部最优。

一个蚂蚁选择一个确定路径的概率,不仅取决于信息素地浓度,同时也取决于该蚂蚁所看到的信息。

信息素的痕迹不能无限增加,因此,需要引入“挥发”机制。

蚁群算法(Ant Algorithms)由此获得灵感而设计出的算法称蚁群算法ant algorithms(或蚁群系统ant systems)蚁群算法(系统)是一种基于群体策略的搜索方法。

有一群蚂蚁,每个蚂蚁找到一个解,然后通过某种方式(信息素)与其它蚂蚁通信。

以加速群体向最优解的收敛。

利用条件概率p ij描述前一状态i与后一状态j之间的转移概率。

属于bivariate model。

蚁群算法(Ant Algorithms)蚁群算法可以用于解决许多组合优化问题,只要能做到用一个图表来阐述将要解决的问题,能定义一种正反馈过程(如TSP 问题中的残留信息) ,问题结构本身能提供解题用的启发式信息(如TSP 问题中城市间的距离) ,约束机制的建立(如TSP 问题中已访问城市的列表) 。

蚁群算法(C语言实现)

蚁群算法(C语言实现)

蚁群算法(C语⾔实现)蚁群算法(ant colony optimization, ACO),⼜称蚂蚁算法,是⼀种⽤来在图中寻找优化路径的机率型算法。

它由Marco Dorigo于1992年在他的中提出,其灵感来源于蚂蚁在寻找⾷物过程中发现路径的⾏为。

蚁群算法是⼀种模拟进化算法,初步的研究表明该算法具有许多优良的性质.针对参数优化设计问题,将蚁群算法设计的结果与遗传算法设计的结果进⾏了⽐较,数值仿真结果表明,蚁群算法具有⼀种新的模拟进化优化⽅法的有效性和应⽤价值。

预期的结果: 各个蚂蚁在没有事先告诉他们⾷物在什么地⽅的前提下开始寻找⾷物。

当⼀只找到⾷物以后,它会向⼀种信息素,吸引其他的蚂蚁过来,这样越来越多的蚂蚁会找到⾷物!有些蚂蚁并没有象其它蚂蚁⼀样总重复同样的路,他们会另辟蹊径,如果令开辟的道路⽐原来的其他道路更短,那么,渐渐,更多的蚂蚁被吸引到这条较短的路上来。

最后,经过⼀段时间运⾏,可能会出现⼀条最短的路径被⼤多数蚂蚁重复着。

原理: 为什么⼩⼩的蚂蚁能够找到⾷物?他们具有智能么?设想,如果我们要为蚂蚁设计⼀个⼈⼯智能的程序,那么这个程序要多么复杂呢?⾸先,你要让蚂蚁能够避开障碍物,就必须根据适当的地形给它编进指令让他们能够巧妙的避开障碍物,其次,要让蚂蚁找到⾷物,就需要让他们遍历空间上的所有点;再次,如果要让蚂蚁找到最短的路径,那么需要计算所有可能的路径并且⽐较它们的⼤⼩,⽽且更重要的是,你要⼩⼼翼翼的编程,因为程序的错误也许会让你前功尽弃。

这是多么不可思议的程序!太复杂了,恐怕没⼈能够完成这样繁琐冗余的程序。

然⽽,事实并没有你想得那么复杂,上⾯这个程序每个蚂蚁的核⼼程序编码不过100多⾏!为什么这么简单的程序会让蚂蚁⼲这样复杂的事情?答案是:简单规则的涌现。

事实上,每只蚂蚁并不是像我们想象的需要知道整个世界的信息,他们其实只关⼼很⼩范围内的眼前信息,⽽且根据这些局部信息利⽤⼏条简单的规则进⾏决策,这样,在蚁群这个集体⾥,复杂性的⾏为就会凸现出来。

蚁群算法小程序(CC++语言实现)

蚁群算法小程序(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,&regs0,&regs0);}void ResetCur(void){union REGS regs0;regs0.h.ah=1;regs0.h.ch=0x06;regs0.h.cl=0x07;int86(0x10,&regs0,&regs0);}/* ------------ 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 */}算法解释:程序开始运⾏,蚂蚁们开始从窝⾥出动了,寻找⾷物;他们会顺着屏幕爬满整个画⾯,直到找到⾷物再返回窝。

蚁群算法 C语言程序(已运行)

蚁群算法 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++)

蚁群算法源代码

蚁群算法源代码

view plaincopy to clipboardprint?/**********************************作者:陈杰*单位:四川大学计算机学院*邮件地址:scucj@*完成时间:2008年3月*********************************/#include<iostream>#include<math.h>#include<time.h>using namespace std;//该程序是以蚁群系统为模型写的蚁群算法程序(强调:非蚂蚁周模型),以三个著名的TSP 问题为测试对象//通过微调参数,都可以获得较好的解/*//----------(1)问题一:Oliver 30 城市TSP 问题best_length = 423.7406; ------------------------ //该程序最好的结果是423.741,可运行多次获得//城市节点数目#define N 30//城市坐标double C[N][2]={{2,99},{4,50},{7,64},{13,40},{18,54},{18,40},{22,60},{24,42},{25,62},{25,38},{37,84},{41,94},{41,26},{44,35},{45,21},{54,67},{54,62},{58,35},{58,69},{62,32},{64,60},{68,58},{71,44},{71,71},{74,78},{82,7},{83,46},{83,69},{87,76},{91,38}};//----------上面参数是固定的,下面的参数是可变的-----------//蚂蚁数量#define M 30//最大循环次数NcMaxint NcMax = 500;//信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q0double alpha = 2, beta = 3, rou = 0.1, alpha1 = 0.1, qzero = 0.01;//-----------问题一结束------------------------------------------------------------------------*//*//----------(2)问题二:Elion50 城市TSP 问题best_length = 427.96; ---------------------------- //该程序最好的结果是428.468,可运行多次获得//城市节点数目#define N 50//城市坐标double C[N][2]={{5,64}, {5,25}, {5,6}, {7,38}, {8,52}, {10,17},{12,42}, {13,13}, {16,57}, {17,33}, {17,63},{20,26}, {21,47}, {21,10}, {25,32}, {25,55},{27,68}, {27,23}, {30,48}, {30,15}, {31,62},{31,32}, {32,22}, {32,39}, {36,16}, {37,69},{37,52}, {38,46}, {39,10}, {40,30}, {42,57},{42,41}, {43,67}, {45,35}, {46,10}, {48,28},{49,49}, {51,21}, {52,33}, {52,41}, {52,64},{56,37}, {57,58}, {58,27}, {58,48}, {59,15},{61,33}, {62,42}, {62,63}, {63,69}};//----------上面参数是固定的,下面的参数是可变的-----------//蚂蚁数量#define M 50//最大循环次数NcMaxint NcMax = 1000;//信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q0double alpha = 2, beta = 4, rou = 0.1, alpha1 = 0.1, qzero = 0.01;//-----------问题二结束------------------------------------------------------------------------*///----------(3)问题三:Elion75 城市TSP 问题best_length = 542.31;//该程序最好的结果是542.309,可运行多次获得//城市节点数目#define N 75//城市坐标double C[N][2]={{6,25}, {7,43}, {9,56}, {10,70}, {11,28},{12,17}, {12,38}, {15,5}, {15,14}, {15,56},{16,19}, {17,64}, {20,30}, {21,48}, {21,45},{21,36}, {22,53}, {22,22}, {26,29}, {26,13},{26,59}, {27,24}, {29,39}, {30,50}, {30,20},{30,60}, {31,76}, {33,34}, {33,44}, {35,51},{35,16}, {35,60}, {36,6}, {36,26}, {38,33},{40,37}, {40,66}, {40,60}, {40,20}, {41,46},{43,26}, {44,13}, {45,42}, {45,35}, {47,66},{48,21}, {50,30}, {50,40}, {50,50}, {50,70},{50,4}, {50,15}, {51,42}, {52,26}, {54,38},{54,10}, {55,34}, {55,45}, {55,50}, {55,65},{55,57}, {55,20}, {57,72}, {59,5}, {60,15},{62,57}, {62,48}, {62,35}, {62,24}, {64,4},{65,27}, {66,14}, {66,8}, {67,41}, {70,64}};//----------上面参数是固定的,下面的参数是可变的-----------//蚂蚁数量#define M 75//最大循环次数NcMaxint NcMax =1000;//信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q0double alpha = 2, beta = 5, rou = 0.1, alpha1 = 0.1, qzero = 0.1;//-----------问题三结束------------------------------------------------------------------------//===================================================================== ======================================//局部更新时候使用的的常量,它是由最近邻方法得到的一个长度//什么是最近邻方法?:)就是从源节点出发,每次选择一个距离最短的点来遍历所有的节点得到的路径//每个节点都可能作为源节点来遍历double Lnn;//矩阵表示两两城市之间的距离double allDistance[N][N];//计算两个城市之间的距离double calculateDistance(int i, int j){return sqrt(pow((C[i][0]-C[j][0]),2.0) + pow((C[i][1]-C[j][1]),2.0));}//由矩阵表示两两城市之间的距离void calculateAllDistance(){for(int i = 0; i < N; i++){for(int j = 0; j < N; j++){if (i != j){allDistance[i][j] = calculateDistance(i, j);allDistance[j][i] = allDistance[i][j];}}}}//获得经过n个城市的路径长度double calculateSumOfDistance(int* tour){double sum = 0;for(int i = 0; i< N ;i++){int row = *(tour + 2 * i);int col = *(tour + 2* i + 1);sum += allDistance[row][col];}return sum;}class ACSAnt;class AntColonySystem{private:double info[N][N], visible[N][N];//节点之间的信息素强度,节点之间的能见度public:AntColonySystem(){}//计算当前节点到下一节点转移的概率double Transition(int i, int j);//局部更新规则void UpdateLocalPathRule(int i, int j);//初始化void InitParameter(double value);//全局信息素更新void UpdateGlobalPathRule(int* bestTour, int globalBestLength);};//计算当前节点到下一节点转移的概率double AntColonySystem::Transition(int i, int j){if (i != j){return (pow(info[i][j],alpha) * pow(visible[i][j], beta));}else{return 0.0;}}//局部更新规则void AntColonySystem::UpdateLocalPathRule(int i, int j){info[i][j] = (1.0 - alpha1) * info[i][j] + alpha1 * (1.0 / (N * Lnn));info[j][i] = info[i][j];}//初始化void AntColonySystem::InitParameter(double value){//初始化路径上的信息素强度tao0for(int i = 0; i < N; i++){for(int j = 0; j < N; j++){info[i][j] = value;info[j][i] = value;if (i != j){visible[i][j] = 1.0 / allDistance[i][j];visible[j][i] = visible[i][j];}}}}//全局信息素更新void AntColonySystem::UpdateGlobalPathRule(int* bestTour, int globalBestLength) {for(int i = 0; i < N; i++){int row = *(bestTour + 2 * i);int col = *(bestTour + 2* i + 1);info[row][col] = (1.0 - rou) * info[row][col] + rou * (1.0 / globalBestLength);info[col][row] =info[row][col];}}class ACSAnt{private:AntColonySystem* antColony;protected:int startCity, cururentCity;//初始城市编号,当前城市编号int allowed[N];//禁忌表int Tour[N][2];//当前路径int currentTourIndex;//当前路径索引,从0开始,存储蚂蚁经过城市的编号public:ACSAnt(AntColonySystem* acs, int start){antColony = acs;startCity = start;}//开始搜索int* Search();//选择下一节点int Choose();//移动到下一节点void MoveToNextCity(int nextCity);};//开始搜索int* ACSAnt::Search(){cururentCity = startCity;int toCity;currentTourIndex = 0;for(int i = 0; i < N; i++){allowed[i] = 1;}allowed[cururentCity] = 0;int endCity;int count = 0;do{count++;endCity = cururentCity;toCity = Choose();if (toCity >= 0){MoveToNextCity(toCity);antColony->UpdateLocalPathRule(endCity, toCity);cururentCity = toCity;}}while(toCity >= 0);MoveToNextCity(startCity);antColony->UpdateLocalPathRule(endCity, startCity);return *Tour;}//选择下一节点int ACSAnt::Choose(){int nextCity = -1;double q = rand()/(double)RAND_MAX;//如果q <= q0,按先验知识,否则则按概率转移,if (q <= qzero){double probability = -1.0;//转移到下一节点的概率for(int i = 0; i < N; i++){//去掉禁忌表中已走过的节点,从剩下节点中选择最大概率的可行节点if (1 == allowed[i]){double prob = antColony->Transition(cururentCity, i);if (prob > probability){nextCity = i;probability = prob;}}}}else{//按概率转移double p = rand()/(double)RAND_MAX;//生成一个随机数,用来判断落在哪个区间段double sum = 0.0;double probability = 0.0;//概率的区间点,p 落在哪个区间段,则该点是转移的方向//计算概率公式的分母的值for(int i = 0; i < N; i++){if (1 == allowed[i]){sum += antColony->Transition(cururentCity, i);}}for(int j = 0; j < N; j++){if (1 == allowed[j] && sum > 0){probability += antColony->Transition(cururentCity, j)/sum;if (probability >= p || (p > 0.9999 && probability > 0.9999)){nextCity = j;break;}}}}return nextCity;}//移动到下一节点void ACSAnt::MoveToNextCity(int nextCity){allowed[nextCity]=0;Tour[currentTourIndex][0] = cururentCity;Tour[currentTourIndex][1] = nextCity;currentTourIndex++;cururentCity = nextCity;}//------------------------------------------//选择下一个节点,配合下面的函数来计算的长度int ChooseNextNode(int currentNode, int visitedNode[]){int nextNode = -1;double shortDistance = 0.0;for(int i = 0; i < N; i++){//去掉已走过的节点,从剩下节点中选择距离最近的节点if (1 == visitedNode[i]){if (shortDistance == 0.0){shortDistance = allDistance[currentNode][i];nextNode = i;}if(shortDistance < allDistance[currentNode][i]){nextNode = i;}}}return nextNode;}//给一个节点由最近邻距离方法计算长度double CalAdjacentDistance(int node){double sum = 0.0;int visitedNode[N];for(int j = 0; j < N; j++){visitedNode[j] = 1;}visitedNode[node] = 0;int currentNode = node;int nextNode;do{nextNode = ChooseNextNode(currentNode, visitedNode);if (nextNode >= 0){sum += allDistance[currentNode][nextNode];currentNode= nextNode;visitedNode[currentNode] = 0;}}while(nextNode >= 0);sum += allDistance[currentNode][node];return sum;}//---------------------------------结束---------------------------------------------//--------------------------主函数-------------------------------------------------- int main(){time_t timer,timerl;time(&timer);unsigned long seed = timer;seed %= 56000;srand((unsigned int)seed);//由矩阵表示两两城市之间的距离calculateAllDistance();//蚁群系统对象AntColonySystem* acs = new AntColonySystem();ACSAnt* ants[M];//蚂蚁均匀分布在城市上for(int k = 0; k < M; k++){ants[k] = new ACSAnt(acs, (int)(k%N));}calculateAllDistance();//随机选择一个节点计算由最近邻方法得到的一个长度int node = rand() % N;Lnn = CalAdjacentDistance(node);//各条路径上初始化的信息素强度double initInfo = 1 / (N * Lnn);acs->InitParameter(initInfo);//全局最优路径int globalTour[N][2];//全局最优长度double globalBestLength = 0.0;for(int i = 0; i < NcMax; i++){//局部最优路径int localTour[N][2];//局部最优长度double localBestLength = 0.0;//当前路径长度double tourLength;for(int j = 0; j < M; j++){int* tourPath = ants[j]->Search();tourLength = calculateSumOfDistance(tourPath);//局部比较,并记录路径和长度if(tourLength < localBestLength || abs(localBestLength - 0.0) < 0.000001){for(int m = 0; m< N; m++){int row = *(tourPath + 2 * m);int col = *(tourPath + 2* m + 1);localTour[m][0] = row;localTour[m][1] = col;}localBestLength = tourLength;}}//全局比较,并记录路径和长度if(localBestLength < globalBestLength || abs(globalBestLength - 0.0) < 0.000001){for(int m = 0; m< N; m++){globalTour[m][0] = localTour[m][0];globalTour[m][1] = localTour[m][1];}globalBestLength = localBestLength;}acs->UpdateGlobalPathRule(*globalTour, globalBestLength);//输出所有蚂蚁循环一次后的迭代最优路径cout<<"第"<<i + 1<<" 迭代最优路径:"<<localBestLength<<"."<<endl;for(int m = 0; m< N; m++){cout<<localTour[m][0]<<".";}cout<<endl;}//输出全局最优路径cout<<"全局最优路径长度:"<<globalBestLength<<endl;cout<<"全局最优路径:";for(int m = 0; m< N; m++){cout<<globalTour[m][0]<<".";}cout<<endl;time(&timerl);int t = timerl - timer;return 0;}//--------------------------主函数结束--------------------------------------------------本文来自CSDN博客,转载请标明出处:/scucj/archive/2009/07/28/4385650.aspx。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

蚁群算法(C语言实现)/s/blog_6bb1b4b001016pt0.html\这是我2012年第一个学期的期末大作业。

不得不说这段代码参考了网络上的一些代码,以及书本上的一些相关数据。

但是无论是网络上还是书上难免总是有很多C++的影子,这是我自己理解之后用C编写的蚁群算法的代码。

这几个城市的相关测试数据在CSDN上可以找到。

//蚁群算法关于简单的TSP问题求解//#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<time.h>#define M 13 //蚂蚁的数量#define N 144 //城市的数量#define R 1000 //迭代次数#define IN 1 //初始化的信息素的量#define MAX 0x7fffffff //定义最大值struct coordinate{char city[15]; //城市名int x; //城市相对横坐标int y; //城市相对纵坐标}coords[N];double graph[N][N]; //储存城市之间的距离的邻接矩阵,自己到自己记作MAX double phe[N][N]; //每条路径上的信息素的量double add[N][N]; //代表相应路径上的信息素的增量double yita[N][N]; //启发函数,yita[i][j]=1/graph[i][j]int vis[M][N]; //标记已经走过的城市int map[M][N]; //map[K][N]记录第K只蚂蚁走的路线double solution[M]; //记录某次循环中每只蚂蚁走的路线的距离int bestway[N]; //记录最近的那条路线double bestsolution=MAX;int NcMax; //代表迭代次数,理论上迭代次数越多所求的解更接近最优解,最具有说服力double alpha,betra,rou,Q;void Initialize(); //信息初始化void Inputcoords(FILE *fp); //将文件中的坐标信息读入void GreateGraph(); //根据坐标信息建图double Distance(int *p); //计算蚂蚁所走的路线的总长度void Result(); //将结果保存到out.txt中void Initialize(){alpha=2; betra=2; rou=0.7; Q=5000;NcMax=R;return ;}void Inputcoords(FILE *fp){int i;int number;if(fp==NULL){printf("Sorry,the file is not exist\n");exit(1);}else{for(i=0; i<N; ++i){fscanf(fp,"%d%s",&number,coords[i].city); fscanf(fp,"%d,%d",&coords[i].x,&coords[i].y); }}}void GreateGraph( ){int i,j;double d;for(i=0; i<N-1; ++i){graph[i][i]=MAX; //自己到自己标记为无穷大for(j=i+1; j<N; ++j){d=(double)((coords[i].x-coords[j].x)*(coords[i].x-coords[j].x)+(coords[i].y-coo rds[j].y)*(coords[i].y-coords[j].y));graph[j][i]=graph[i][j]=sqrt(d);}}graph[N-1][N-1]=MAX;return ;}double Distance(int *p){double d=0;int i;for(i=0; i<N-1; ++i)d+=graph[*(p+i)][*(p+i+1)];}d+=graph[*(p+i)][*(p)];return d;}void Result(){FILE *fl;int i;fl = fopen("out.txt","a"); //将结果保存在out.txt这个文件里面fprintf(fl,"%s\n","本次算法中的各参数如下:");fprintf(fl,"alpha=%.3lf, betra=%.3lf, rou=%.3lf, Q=%.3lf\n",alpha,betra,rou,Q); fprintf(fl,"%s %d\n","本次算法迭代次数为:",NcMax);fprintf(fl,"%s %.4lf\n","本算法得出的最短路径长度为:",bestsolution);fprintf(fl,"%s\n","本算法求得的最短路径为:");for(i=0; i<N; ++i)fprintf(fl,"%s → ",coords[bestway[i]].city);fprintf(fl,"%s",coords[bestway[0]].city);fprintf(fl,"\n\n\n");fclose(fl);return ;int main(){int NC=0;int i,j,k;int s;double drand,pro,psum;FILE *fp;Initialize();fp = fopen("coords.txt","r+");Inputcoords(fp);GreateGraph();fclose(fp);for(i=0; i<N; ++i){for(j=0; j<N; ++j){phe[i][j]=IN; //信息素初始化if(i!=j)yita[i][j]=100.0/graph[i][j]; //期望值,与距离成反比}}memset(map,-1,sizeof(map)); //把蚂蚁走的路线置空memset(vis,0,sizeof(vis)); //0表示未访问,1表示已访问srand(time(NULL));while(NC++<=NcMax){for(k=0; k<M; ++k){map[k][0]=(k+NC)%N; //给每只蚂蚁分配一个起点,并且保证起点在N个城市里 vis[k][map[k][0]]=1; //将起点标记为已经访问}s=1;while(s<N){for(k=0; k<M; ++k){psum=0;for(j=0; j<N; ++j){if(vis[k][j]==0){psum+=pow(phe[map[k][s-1]][j],alpha)*pow(yita[map[k][s-1]][j],betra); }}drand=(double)(rand()P00);drand/=5000.0; //生成一个小于1的随机数pro=0;for(j=0; j<N; ++j){if(vis[k][j]==0)pro+=pow(phe[map[k][s-1]][j],alpha)*pow(yita[map[k][s-1]][j],betra)/psum; if(pro>drand)break;}vis[k][j]=1; //将走过的城市标记起来map[k][s]=j; //记录城市的顺序}s++;}memset(add,0,sizeof(add));for(k=0; k<M; ++k) //计算本次中的最短路径//{solution[k]=Distance(map[k]); //蚂蚁k所走的路线的总长度if(solution[k]<bestsolution){bestsolution=solution[k];for(i=0; i<N; ++i)bestway[i]=map[k][i];}}for(k=0; k<M; ++k){for(j=0; j<N-1; ++j){add[map[k][j]][map[k][j+1]]+=Q/solution[k];}add[N-1][0]+=Q/solution[k];}for(i=0; i<N; ++i){for(j=0; j<N; ++j){phe[i][j]=phe[i][j]*rou+add[i][j];if(phe[i][j]<0.0001) //设立一个下界phe[i][j]=0.0001;else if(phe[i][j]>20) //设立一个上界,防止启发因子的作用被淹没phe[i][j]=20;}}memset(vis,0,sizeof(vis));memset(map,-1,sizeof(map));}Result();printf("Result is saved in out.txt\n"); return 0;}。

相关文档
最新文档