蚁群算法求解TSP
clear; clc; close all;
Ant_Num=50;
Alpha=1; %信息素权重
Beta=5; %启发式因子权重
Rho=0.1; %信息素消失系数
G=200; %迭代次数
Q=100;%信息素增加强度系数
City_Num=20; %城市数量
border=100; %城市边界
City=[rand(City_Num,1)*border,rand(City_Num,1)*border]; %随机城市坐标
% City=[9.442061706065957e+01 5.554527461175734e+01
% 7.033585927645424e+01 8.210485000479132e+01
% 8.513885160801584e+01 2.875386430880210e+01
% 7.639317665257967e+01 9.899454527886692e+01
% 4.124371269556116e+01 3.075543952877445e+01
% 5.845739036088576e+01 6.394249385784040e+01
% 2.047038459263265e+01 3.416955672791446e+01
% 9.556319529767441e+01 5.075386755815181e+01
% 6.864343351256032e+01 9.524654717191730e+01
% 9.348728571015130e+01 4.280562205659413e+01
% 3.436836073417421e+01 7.104795575132123e+01
% 9.817321649623470e+01 2.501489907029606e+01
% 7.820931971241255e+01 7.332155697803887e+01
% 8.988323696914080e+01 4.302811953719409e+01
% 3.575739586131570e+01 9.099463432988888e+01
% 8.563041161898965e+00 4.548622350697822e+01
% 6.563114202893138e+01 2.278268090861504e+01
% 9.477447526974635e+01 9.126965924351660e+01
% 4.261772603974462e+01 2.400688433476272e+01
% 4.447512148263895e+01 6.468043451289284e+01];
% %%
D=zeros(City_Num);
for i=1:City_Num
for j=1:City_Num
if i~=j
D(i,j)=sqrt((City(i,1)-City(j,1))^2+(City(i,2)-City(j,2))^2);
else
D(i,j)=eps;
end
end
end
Eta=1./D; %启发因子,即越长走的可能性越小
Tau=ones(City_Num); %信息素矩阵
Tabu=zeros(Ant_Num,City_Num); %记录路径
gen=1; %迭代次数
Best_Record=zeros(G,City_Num); %每代最优路径
Length_Record=inf.*ones(G,1); %每代最短距离
figure(1);
while gen<=G
Randpos=[];
for i=1:(ceil(Ant_Num/City_Num)) %每个城市平均放多少蚂蚁
Randpos=[Randpos,randperm(City_Num)]; %每一堆蚂蚁随机放到城市
end
Tabu(:,1)=Randpos(1,1:Ant_Num)';
for j=2:City_Num
for i=1:Ant_Num
visited=Tabu(i,1:(j-1)); %当前蚂蚁已经访问过的城市
J=zeros(1,(City_Num-j+1)); %未访问过的城市
P=J;
Jc=1;
for k=1:City_Num
if length(find(visited==k))==0 %将没有访问过的城市加入
J(Jc)=k;
Jc=Jc+1;
end
end
for k=1:length(J)
P(k)=(Tau(visited(end),J(k))^Alpha)*(Eta(visited(end),J(k))^Beta);
end
Pcum=cumsum(P/sum(P));%赌轮盘操作
select=find(Pcum>=rand);%当前蚂蚁选择的下一个城市
to_visit=J(select(1));
Tabu(i,j)=to_visit;
end
end
if gen>=2
Tabu(1,:)=Best_Record(gen-1,:); %留下上一轮的最短路径
end
L=zeros(Ant_Num,1); %根据路径计算每只蚂蚁的走过距离
for i=1:Ant_Num
R=Tabu(i,:);
for j=1:(City_Num-1)
L(i)=L(i)+D(R(j),R(j+1));
end
L(i)=L(i)+D(R(1),R(City_Num));
end
Length_Record(gen)=min(L); %最短路径的距离
pos=find(L==min(L));
Best_Record(gen,:)=Tabu(pos(1),:);%最短路径
Delta_Tau=zeros(City_Num); %以下更新信息素增量
for i=1:Ant_Num
for j=1:City_Num-1
Delta_Tau(Tabu(i,j),Tabu(i,j+1))=Delta_Tau(Tabu(i,j),Tabu(i,j+1))+Q/L(i);
end
Delta_Tau(Tabu(i,City_Num),Tabu(i,1))= Delta_Tau(Tabu(i,City_Num),Tabu(i,1))+Q/L(i);
end
Tau=(1-Rho).*Tau+Delta_Tau; %信息素更新
Tabu=zeros(Ant_Num,City_Num); %路径清空
%以下为画图部分
for i=1:City_Num-1
plot([City(Best_Record(gen,i),1),City(Best_Record(gen,i+1),1)],...
[City(Best_Record(gen,i),2),City(Best_Record(gen,i+1),2)],'bo-');
hold on;
end
plot([City(Best_Record(gen,1),1),City(Best_Record(gen,City_Num),1)],...
[City(Best_Record(gen,1),2),City(Best_Record(gen,City_Num),2)],'ro-');
title(['优化最短距离:',num2str(Length_Record(gen))]);
hold off;
pause(0.005);
gen=gen+1;
end
Pos=find(Length_Record==min(Length_Record));
Shortest_Route=Best_Record(Pos(1),:);
Shortest_Length=min(Length_Record);
figure(2);
plot(Length_Record);
xlabel('迭代次数');