3.5w+
社区成员
张三学习了蚁群算法之后特别高兴,他定义了一个特别的图,希望找到图中的最短巡回路径。
张三的图由 2021 个结点组成,依次编号 1 至 2021。
对于两个不同的结点 ,,如果 和 的差的绝对值大于 21,则两个结点之间没有边相连;如果 和 的差的绝对值小于等于 21,则两个点之间有一条 长度为 和 的最小公倍数的无向边相连。
例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无向边,长度为 24;结点 15 和结点 25 之间有一条无向边,长度为 75。
利用蚁群算法确定最短的巡回路径,即从结点 1 出发的最短巡回路径长度是多少。
下面是我的代码,麻烦大家帮忙看看有什么问题,为什么总是得不出一个好的结果,最短路径一直是无穷大?
dist=zeros(80);
for i=1:80
for j=1:i-1
if i-j<=21
dist(i,j)=lcm(i,j);
else
dist(i,j)=inf;
end
end
end
dist=dist+dist'+diag(repmat(1e-6,1,80));
function [shortest_length,shortest_path] =yiqun(dist,antnum,citynum,alpha,beta,rho,Q,max_iter)
%蚁群优化算法 主要用于解决TSP问题
%loc 一行代表一个城市的坐标(暂时将第一个换成dist 原来是loc)
%初始化数据
%[citynum,n]=size(loc);
%dist=yiqun_distance(loc);
Eta=1./dist;
Tao=ones(citynum,citynum);
iter=1;
Ant_path=zeros(antnum,citynum);
Path_best=zeros(max_iter,citynum);
Length_best=inf(max_iter,1);
%Length_ave=zeros(max_iter,1);
%迭代求解
while iter<=max_iter
%{
将各蚂蚁放在随机的起始点上
for k=1:antnum
Ant_path(k,1)=randi(citynum);
end
%}
Ant_path(:,1)=ones(antnum,1);
%allcity=1:citynum;
havevalue=ones(antnum,1);
for k=1:antnum
for i=2:citynum
lastcity=Ant_path(k,1:i-1);
allcity=max(1,lastcity(end)-21):min(lastcity(end)+21,citynum);
allowindex=(~ismember(allcity,lastcity));
allowcity=allcity(allowindex);
if sum(allowindex)~=0
P=zeros(1,length(allowcity));
for j=1:length(allowcity)
P(j)=Tao(lastcity(end),allowcity(j))^alpha*Eta(lastcity(end),allowcity(j))^beta;
end
P=P/sum(P);
%轮盘赌确定下一个地点
pc=cumsum(P);
rd=rand;
while rd==1
rd=rand;
end
nextindex=find(pc>rd);
if length(allowcity)==1
a=1;
end
if i==citynum
Ant_path(k,i)=allowcity(1);
else
Ant_path(k,i)=allowcity(nextindex(1));
end
else
havevalue(k)=0;
break;
end
end
end
%计算各个蚂蚁走过的路径长度,用来确定ΔTao,由此来改变Tao的值
Pathlength=zeros(antnum,1);
for i=1:antnum
if havevalue(i)==1
if isinf(dist(Ant_path(i,citynum),Ant_path(i,1)))
havevalue(i)=0;
Pathlength(i)=inf;
else
for j=1:citynum-1
Pathlength(i)=Pathlength(i)+dist(Ant_path(i,j),Ant_path(i,j+1));
end
Pathlength(i)=Pathlength(i)+dist(Ant_path(i,citynum),Ant_path(i,1));
end
else
Pathlength(i)=inf;
end
end
%更新信息素
delta_Tao=zeros(citynum,citynum);
for i=1:antnum
if havevalue(i)==1
for j=1:citynum-1
delta_Tao(Ant_path(i,j),Ant_path(i,j+1))=delta_Tao(Ant_path(i,j),Ant_path(i,j+1))+Q/Pathlength(i);
end
delta_Tao(Ant_path(i,citynum),Ant_path(i,1))=delta_Tao(Ant_path(i,citynum),Ant_path(i,1))+Q/Pathlength(i);
end
end
Tao=(1-rho)*Tao+delta_Tao;
%计算最短路径及总路长 平均路长
if ~isinf(min(Pathlength))
[bestlength,bestindex]=min(Pathlength);
if iter==1
Length_best(iter,1)=bestlength;
Path_best(iter,:)=Ant_path(bestindex,:);
else
if bestlength<Length_best(iter-1,1)
Length_best(iter,1)=bestlength;
Path_best(iter,:)=Ant_path(bestindex,:);
else
Length_best(iter,1)=Length_best(iter-1,1);
Path_best(iter,:)=Path_best(iter-1,:);
end
end
%Length_ave(iter,:)=mean(Pathlength);
else
if iter~=1
Length_best(iter,1)=Length_best(iter-1,1);
Path_best(iter,:)=Path_best(iter-1,:);
end
end
%清除路径信息,准备下一轮的迭代
Ant_path=zeros(antnum,citynum);
iter=iter+1;
end
shortest_length=Length_best(end,1);
shortest_path=Path_best(end,:);
%绘图
if ~isinf(shortest_length)
figure(1)
plot(1:max_iter,Length_best,'b','linewidth',1);
%hold on
%plot(1:max_iter,Length_ave,'r','linewidth',1);
%hold off
xlabel("迭代次数");ylabel("路径长度");
legend('最短路径长度');
title("最短路径长度");
end
end