全国环游怎么走----蚁群算法

正在看数学建模的算法,这里讲蚁群算法拿出来做了个全国省会级城市旅游路线最短问题(TSP),使用matlab实现。

蚁群算法思想

(1)根据具体问题设置多只蚂蚁,分头并行搜索。
(2)每只蚂蚁完成一次周游后,在行进的路上释放信息素,信息素量与解的质量成正比。
(3)蚂蚁路径的选择根据信息素强度大小(初始信息素量设为相等),同时考虑两点之间的距离,采用随机的局部搜索策略。这使得距离较短的边,其上的信息素量较大,后来的蚂蚁选择该边的概率也较大。
(4)每只蚂蚁只能走合法路线(经过每个城市1次且仅1次),为此设置禁忌表来控制。
(5)所有蚂蚁都搜索完一次就是迭代一次,每迭代一次就对所有的边做一次信息素更新,原来的蚂蚁死掉,新的蚂蚁进行新一轮搜索。
(6)更新信息素包括原有信息素的蒸发和经过的路径上信息素的增加。
(7)达到预定的迭代步数,或出现停滞现象(所有蚂蚁都选择同样的路径,解不再变化),则算法结束,以当前最优解作为问题的最优解。

调用函数:

function [R_best,L_best,L_ave,Shortest_Route,Shortest_Length] = ACATSP(path,NC_max,m,Alpha,Beta,Rho,Q)

matlab程序

程序主体来源互联网。数据集为国内主要城市的经纬度,及地名,以

经度,纬度,地名

的格式存入path所指向的txt文件,该txt文件与该matlab程序放在同一目录。

function [R_best,L_best,L_ave,Shortest_Route,Shortest_Length] = ACATSP(path,NC_max,m,Alpha,Beta,Rho,Q)

%%------------------------------------------------------------------------- %% 主要符号说明

%% C n个城市的坐标,n×2的矩阵 %% NC_max 最大迭代次数
%% m 蚂蚁个数 %% Alpha 表征信息素重要程度的参数
%% Beta 表征启发式因子重要程度的参数 %% Rho 信息素蒸发系数
%% Q 信息素增加强度系数 %% R_best 各代最佳路线
%% L_best 各代最佳路线的长度 %%=========================================================================

%% 第一步:变量初始化 %% 从文件读入数据
[x y z] = textread(path,'%f,%f,%s');
C = [x,y] ;
name = z ;

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)];      % 将蚂蚁编号打乱,依次放入1-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; % 已访问城市的个数,初始化为1,即蚂蚁在初始城市 for k=1:n % find:查找出矩阵中符合要求的元素索引 % length:返回矩阵长度 % 此用法为 当visited != k 时,执行记录该点的操作,目的在于记录下来未访问点。感觉作者想复杂了 if length(find(visited==k))==0 J(Jc)=k; Jc=Jc+1; % 访问的城市个数自加1 end end % 下面计算待选城市的概率分布 for k=1:length(J) % 按照公式计算由当前城市到其他城市的概率 (信息素^Alpha * 能见度^Beta) % 因为信息素矩阵Tau初始值全为1,所有第一次的概率矩阵为该城市的能见度值 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的列向量,记录m只蚂蚁走过路径的长度 for i=1:m R=Tabu(i,:); % R矩阵记录本次迭代第i只蚂蚁走过的路径 for j=1:(n-1) % 循环求出第i只蚂蚁走过的路径的总长度 L(i)=L(i)+D(R(j),R(j+1)); % 原距离加上第j个城市到第j+1个城市的距离 end L(i)=L(i)+D(R(1),R(n)); % 从最后一个城市走回原点 end L_best(NC)=min(L); % 最佳距离取最小 pos=find(L==L_best(NC)); % 通过find找到 本次迭代m只蚂蚁中路径最短的那只的索引 R_best(NC,:)=Tabu(pos(1),:); % 此轮迭代后的最佳路线 L_ave(NC)=mean(L); % 此轮迭代后的平均距离 NC=NC+1 % 迭代继续 %% 第五步:更新信息素 Delta_Tau=zeros(n,n); % 设置全0矩阵,记录本次迭代蚂蚁走过路径的信息素,用来更新初始信息素矩阵 for i=1:m for j=1:(n-1) % 找出第i只蚂蚁走过的前后两个城市节点,增加其信息素 Delta_Tau(Tabu(i,j),Tabu(i,j+1))=Delta_Tau(Tabu(i,j),Tabu(i,j+1))+Q/L(i); end % 第i只蚂蚁走完所有城市,返回其实城市的路径同样增加信息素 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)) %最大迭代次数后最短距离 subplot(1,2,1) %绘制第一个子图形 DrawRoute(C,Shortest_Route,name) %画路线图的子函数 subplot(1,2,2) %绘制第二个子图形 plot(L_best) hold on %保持图形 plot(L_ave,'r') title('平均距离和最短距离') %标题 function DrawRoute(C,R,name) %%========================================================================= %% DrawRoute.m %% 画路线图的子函数 %%------------------------------------------------------------------------- %% C Coordinate 节点坐标,由一个N×2的矩阵存储 %% R Route 路线 %%========================================================================= N=length(R); scatter(C(:,1),C(:,2)); % 画散点图 text(C(:,1),C(:,2),[name(:,1)]) % 对散点图做地名标签 hold on plot([C(R(1),1),C(R(N),1)],[C(R(1),2),C(R(N),2)],'g') hold on for ii=2:N plot([C(R(ii-1),1),C(R(ii),1)],[C(R(ii-1),2),C(R(ii),2)],'g') hold on end title('全国环游怎么走!? ')

运行结果

当NC_max = 10 (迭代10代)
《全国环游怎么走----蚁群算法》

当NC_max = 100 (迭代100代)
《全国环游怎么走----蚁群算法》

当NC_max = 1000 (迭代1000代)
《全国环游怎么走----蚁群算法》

通过信息素的更新,认识蚁群算法

首次迭代,信息素的更新值矩阵:

《全国环游怎么走----蚁群算法》

首次迭代,考虑信息挥发后,更新后的信息素矩阵:
《全国环游怎么走----蚁群算法》

100次迭代,信息素的更新值矩阵:
《全国环游怎么走----蚁群算法》

100次迭代,考虑信息挥发后,更新后的信息素矩阵:
《全国环游怎么走----蚁群算法》

结论

1、可以看到,在迭代400次以后,均值和最小值重合,达到最优化。从绘制出的路线图看,也符合我们直观的认识。
2、程序中,如果确实这段代码,会出现无法达到平稳最优解的状态,目前还不知道原因。

 if NC>=2
        % 将上一次迭代最优结果赋给第一只蚂蚁,感觉像遗传,保留上一次最优结果
        Tabu(1,:)=R_best(NC-1,:);
    end

运行结果:
1)迭代400次左右达到最优,出现频率低
《全国环游怎么走----蚁群算法》
1)迭代2000次左右任然在无法收敛,出现频率高
《全国环游怎么走----蚁群算法》

参考

蚁群算法(独辟蹊径的进化算法)

    原文作者:蚁群算法
    原文地址: https://blog.csdn.net/sinat_34022298/article/details/77748741
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞