问题定义:巡回旅行商问题
给定一组n个城市和俩俩之间的直达距离,寻找一条闭合的旅程,使得每个城市刚好经过一次且总的旅行距离最短。TSP问题也称为货郎担问题,是一个古老的问题。最早可以追溯到1759年Euler提出的骑士旅行的问题。1948年,由美国兰德公司推动,TSP成为近代组合优化领域的典型难题。TSP是一个具有广泛的应用背景和重要理论价值的组合优化问题。近年来,有很多解决该问题的较为有效的算法不断被推出,例如Hopfield神经网络方法,模拟退火方法以及遗传算法方法等。TSP搜索空间随着城市数n的增加而增大,所有的旅程路线组合数为(n-1)!/2。在如此庞大的搜索空间中寻求最优解,对于常规方法和现有的计算工具而言,存在着诸多计算困难。借助蚁群算法的搜索能力解决TSP问题,是很自然的想法。
根据仿生学家的研究结果,蚂蚁凭借路径寻优的能力能够找到蚁巢与食物之间的最短路径,其原理在于:蚂蚁在所经过的路径上留下一种挥发性分泌物(pheromone,以下称为信息素),信息素随着时间的推移会逐渐挥发消失.蚂蚁在觅食过程中能够感知这种物质的存在及其强度,并以此来指导自己的运动方向,倾向于朝着这种物质强度高的方向移动,即选择该路径的概率与当时这条路径上该物质的强度成正比.信息素强度越高的路径,选择它的蚂蚁就越多,则在该路径上留下的信息素的强度就更大,而强度大的信息素又吸引更多的蚂蚁,从而形成一种正反馈.通过这种正反馈,蚂蚁最终可以发现最佳路径,导致大部分的蚂蚁都会走此路径.
% C表示n个城市的坐标,n×2的矩阵
% NC_max表示最大迭代次数
% m表示蚂蚁个数
% Alpha表示表征信息素重要程度的参数
% Beta表示表征启发式因子重要程度的参数
% Rho表示信息素蒸发系数
% Q表示信息素增加强度系数
% R_best表示各代最佳路线
% L_best表示各代最佳路线的长度
x=[51 27 56 21 4 6 58 71 54 53 94 18 89 33 12 25 24 58 71 94 17 38 13 82 12 58 45 11 47 4]';
y=[14 81 67 92 64 19 98 18 62 69 30 54 10 46 34 18 42 69 61 78 16 40 10 7 32 17 21 26 35 90]';
C=[x y];
NC_max=50;
m=30;
Alpha=1.4;
Beta=2.2;
Rho=0.15;
Q=10^6;
%%%%%%%%变量初始化%%%%%%%%%%%%%%%%
n=size(C,1); %n表示问题的规模(城市个数)
D=zeros(n,n);%D表示完全图的赋权邻接矩阵
for i=1:n
for j=1:n
if i~=j
D(i,j)=((C(i,1)-C(j,1))^2+(C(i,2)-C(j,2))^2)^0.5;
else
D(i,j)=eps;
%i=j时不计算,应该为0,但后面的启发因子要取倒数,用eps(浮点相对精度)表示
end
D(j,i)=D(i,j); %对称矩阵
end
end
Eta=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)];
end
Tabu(:,1)=(Randpos(1,1:m))';
%%%%%%%%m只蚂蚁按概率函数选择下一座城市,完成各自的周游%%%%%%%%%%%%
for j=2:n %所在城市不计算
for i=1:m
visited=Tabu(i,1:(j-1)); %记录已访问的城市,避免重复访问
J=zeros(1,(n-j+1)); %待访问的城市
P=J; %待访问城市的选择概率分布
Jc=1;
for k=1:n
if length(find(visited==k))==0 %开始时置0
J(Jc)=k;
Jc=Jc+1; %访问的城市个数自加1
end
end
%下面计算待选城市的概率分布
for k=1:length(J)
P(k)=(Tau(visited(end),J(k))^Alpha)*(Eta(visited(end),J(k))^Beta);
end
P=P/(sum(P));
%按概率原则选取下一个城市
Pcum=cumsum(P); %cumsum,元素累加即求和
Select=find(Pcum>=rand); %若计算的概率大于原来的就选择这条路线
to_visit=J(Select(1));
Tabu(i,j)=to_visit;
end
end
if NC>=2
Tabu(1,:)=R_best(NC-1,:);
end
%%%%%%%%记录本次迭代最佳路线%%%%%%%%%%%%
L=zeros(m,1); %开始距离为0,m*1的列向量
for i=1:m
R=Tabu(i,:);
for j=1:(n-1)
L(i)=L(i)+D(R(j),R(j+1)); %原距离加上第j个城市到第j+1个城市的距离
end
L(i)=L(i); %一轮下来后走过的距离
end
L_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); %开始时信息素为n*n的0矩阵
for i=1:m
for 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);
%此次循环在路径(i,j)上的信息素增量
end
Delta_Tau(Tabu(i,n),Tabu(i,1))=Delta_Tau(Tabu(i,n),Tabu(i,1))+Q/L(i);
%此次循环在整个路径上的信息素增量
end
Tau=(1-Rho).*Tau+Delta_Tau; %考虑信息素挥发,更新后的信息素
%%%%%%%%禁忌表清零%%%%%%%%%%%%
Tabu=zeros(m,n); %%直到最大迭代次数
end
%%%%%%%%结果%%%%%%%%%%%%
Pos=find(L_best==min(L_best)); %找到最佳路径(非0为真)
Shortest_Route=R_best(Pos(1),:) %最大迭代次数后最佳路径
Shortest_Length=L_best(Pos(1)) %最大迭代次数后最短距离
figure(1)
subplot(1,2,1); %绘制第一个子图形
DrawRoute(C,Shortest_Route); %画路线图的子函数
subplot(1,2,2); %绘制第二个子图形
plot(L_best);
hold on
plot(L_ave,'r');
title('平均距离和最短距离')
往期回顾>>>>>>
【优化求解】模拟退火遗传实现带时间窗的车辆路径规划问题
【优化算法】遗传算法求最短路径
【优化问题】基于栅格地图——遗传算法的机器人最优路径规划
资源获取
公众号中回复“QQ”加入QQ群;回复“微信”加入微信群;回复“投稿”与大家分享智慧;回复“资源获取”免费下载该资源。
扫描二维码关注公众号,回复:
10799651 查看本文章