概述
蚁群算法的基本思路很简单,即通过人工构造的蚂蚁去寻找最短路径。蚁群算法的基本假定如下:
- 开始时,蚁群随机寻找路径并释放信息素,信息量的多少与路径的长短成反比;
- 后续通过蚂蚁会偏向于走在信息素更多的路径上,同时释放信息素;
- 原有信息素会随时间推移而挥发;
- 重复几次后,越来越多的蚂蚁会聚集到最短的路径上。
在路径优化类问题上,蚁群算法具有效率高、收敛快、易于接近最优解等特点。
流程
总流程图
运行结束条件,可以用次数判断,也可以用残差判断。
单次运行流程图
代码
本文用MATLAB来实现。
先生成供调用的方法ACO.m
function [Shortest_Route,Shortest_Length,ShortLengthList,MiddleLengthList]=ACO(cityList,originCityIndex,antCount,alpha,beta,rho,Q)
tic;
citySize=size( cityList);
ncityList=citySize(1);
distBetweenCity=zeros(ncityList);%%城市之间距离矩阵
yitaBetweenCity=zeros(ncityList);%%城市之间距离系数
tao=zeros(ncityList);%%信息素浓度矩阵
for i=1:ncityList
for j=1:ncityList
distBetweenCity(i,j)=norm(cityList(i,:)-cityList(j,:));
if(i~=j)
yitaBetweenCity(i,j)=1/distBetweenCity(i,j);
end
end
end
Shortest_Length=sum(sum(distBetweenCity));
Shortest_Route=zeros(ncityList+1,1);
runsCount=200;%%运行次数
ShortLengthList=zeros(runsCount,1);
MiddleLengthList=zeros(runsCount,1);
runsIndex=0;%%运行次数
while(runsIndex<=runsCount)
allRoute=zeros(ncityList+1,antCount);
for kk=1:antCount%%对不同的蚂蚁循环
passedCity=zeros(ncityList+1,1);%%经过的城市
passedCityIndex=1;
passedCity(passedCityIndex)=originCityIndex;%%起点城市赋值
passedCity(ncityList+1)=originCityIndex;%%终点城市赋值
for k=1:ncityList-1%%对剩余的点循环
selectionProbability=zeros(ncityList,1);%%选择概率矩阵
for i=1:ncityList
seleced=1;
for j=1:ncityList
if(i==passedCity(j))
seleced=0;
break;
end
end
if(seleced==1)
selectionProbability(i)=tao(i,passedCity(passedCityIndex))^alpha*yitaBetweenCity(i,passedCity(passedCityIndex))^beta;
end
end
if(norm(selectionProbability)==0)
selectionProbability=ones(ncityList,1);
end
selectionProbability=selectionProbability/sum(selectionProbability);
totalProbability=zeros(ncityList,1);
totalProbability(1)=selectionProbability(1);
randValue=rand(1,1);
nextCity=0;%%下一个点的编号
if(randValue<selectionProbability(1))
nextCity=1;
else
for i=2:ncityList
totalProbability(i)=sum(selectionProbability(1:i));
if (randValue<totalProbability(i)&&randValue>=totalProbability(i-1))
nextCity=i;
end
end
end
passedCityIndex=passedCityIndex+1;
passedCity(passedCityIndex)=nextCity;
end
allRoute(:,kk)=passedCity;
end
tao=tao*(1-rho);%%信息素挥发
lengthByEachAnt=zeros(antCount,1);
for kk=1:antCount%%更新信息素并选择最短路径
totalLength=0;%%单条路径总长
passedCity=allRoute(:,kk);
for i=1:ncityList
totalLength=totalLength+distBetweenCity(passedCity(i),passedCity(i+1));
end
lengthByEachAnt(kk)=totalLength;
if(totalLength<Shortest_Length)
Shortest_Length=totalLength;
Shortest_Route=passedCity;
end
for i=1:ncityList
tao(passedCity(i),passedCity(i+1))=tao(passedCity(i),passedCity(i+1))+Q/totalLength; %%走过的路径信息素增加
end
end
ShortLengthList(runsIndex+1)= Shortest_Length;
MiddleLengthList(runsIndex+1)= sum(lengthByEachAnt)/antCount;
runsIndex=runsIndex+1;
end
routeLocation=zeros(ncityList+1,2);
for i=1:ncityList+1
routeLocation(i,:)=cityList(Shortest_Route(i),:);
end
routeLocation=routeLocation';
subplot(1,2,1);
plot(ShortLengthList,'r');
hold on;
plot(MiddleLengthList,'g');
title('平均距离和最短距离') %标题
subplot(1,2,2);
plot(routeLocation(1,:),routeLocation(2,:));
title('旅行商问题优化结果 ');
toc;
运行结果
在0<X<100,0<Y<100的区域内,随机生成100个点,寻找经过每个点的最短路径。
主程序如下:
cityList=100*rand(100,2);
originCityIndex=5; %%起点城市编号
alpha=1; %%表征信息素重要程度的参数
beta=7; %%表征启发式因子重要程度的参数
antCount=50; %%蚂蚁数量
rho=0.3; %%信息素蒸发系数
Q=1; %%信息素增加强度系数
[Shortest_Route,Shortest_Length,ShortLengthList,MiddleLengthList]=ACO(cityList,originCityIndex,antCount,alpha,beta,rho,Q);
运行结果如下图示:
最小距离为874.7373,非常接近理论上的最小路径长度。