一 MATLAB智能算法实现( 二 )

<= NC_max%% Step2:将m只蚂蚁放到n个城市上RandPosition = [];% ceil函数是向上取整,randperm函数是生成随机数列,randper(3)就可能是[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1] 。所以循环m/n次,每一次放n个城市各放一只蚂蚁,最后取前m值蚂蚁(RandPosition(1,1:m)) 。其意义就在于当m = 2n+1时,我可以保证每个城市至少有两只蚂蚁,且有一只蚂蚁是随机出现在任意城市位置的for i = 1:(ceil(m/n))RandPosition = [RandPosition,randperm(n)];end% Tabu(:,1)记录着初始状态下m只蚂蚁的位置Tabu(:,1) = (RandPosition(1,1:m))';%% Step3:这m只蚂蚁去当前位置之外的其它城市的概率,并依据概率最大的原则选择下一步需要到达的城市for j = 2:1:nfor i = 1:1:m% visited是已经走过的城市,J是当前没有走过的城市,P记录着去每一个J中城市的概率visited = Tabu(i,1:(j-1));J = zeros(1,(n-j+1));P = J;Jc = 1;% 这个循环就是生成J的过程,就是在visited中寻找,如果找到了某一城市的编号就跳过,如果没有就把它加入Jfor k = 1:1:nif length(find(visited == k)) == 0J(Jc) = k;Jc = Jc + 1;endend% 去某一城市的概率既由从当前城市到它的路径上的信息素浓度决定,又与路径的长度相关for k = 1:1:length(J)P(k) = (Tau(visited(end),J(k))^Alpha)*(Eta(visited(end),J(k))^Beta);endP = P/sum(P);P_max = P(1);index = 1;for l = 1:1:length(P)if P(l) >= P_maxP_max = P(l);index = l;endend% 找出其中概率最大的目标城市,并把它放入路径表Tabuto_visit = J(index);Tabu(i,j) = to_visit;endend% 当迭代次数大于等于2时,将前一代的最短路径放入Tabu表,进行新一轮的比较,以确保算法的收敛if NC >= 2Tabu(i,:) = R_best(NC-1,:);end%% Step4:计算要输出参数L = zeros(m,1);for i = 1:1:mR = Tabu(i,:);for j = 1:1:(n-1)L(i) = L(i) + D(R(j),R(j+1));end% 这里要特别注意要加上从末点到始点的距离,因为蚂蚁要回到原始位置,这样的总的路径长度的比较才有意义,我们也可以由此知道从哪一个城市开始走会得到最优的效果L(i) = L(i) + D(R(1),R(n)); end% L_best是当前所有m个路径长度中最小的L_best(NC) = min(L);index = find(L == L_best(NC));% 最短路径要从Tabu表中寻找R_best(NC,:) = Tabu(index(1),:);L_ave(NC) = mean(L);NC = NC + 1;%% Step5:更新信息素Delta_Tau = zeros(n,n);% 每一只蚂蚁单次播撒的信息素量是一定的Q,所以一次遍历之后路径上每两个相邻城市间的信息素浓度增加为Q/L(i)(要注意由于最终要回到原点所以始末两点理论上也是相邻的)for i = 1:1:mfor j = 1:1:(n-1)Delta_Tau(Tabu(i,j),Tabu(i,j+1)) = Delta_Tau(Tabu(i,j),Tabu(i,j+1)) + Q/L(i);endDelta_Tau(Tabu(i,n),Tabu(i,1)) = Delta_Tau(Tabu(i,n),Tabu(i,1)) + Q/L(i);end% Rho是挥发系数,描述了信息素浓度的降低速度Tau = (1-Rho).*Tau + Delta_Tau;Tabu = zeros(m,n);end% Step6:图形输出Pos = find(L_best == min(L_best));Shortest_Route = R_best(Pos(1),:);Shortest_Length = L_best(Pos(1));% 左边的图表示在二维空间上NC次迭代后最短路径的分布,右边的图有两个部分,其一是平均距离的变化,其二是最短距离的变化 。算法中的DrawRoute是一个自定义函数,在附件当中这里就不加解释subplot(1,2,1);DrawRoute(C,Shortest_Route);subplot(1,2,2);plot(L_best);hold on;plot(L_ave,'r');title('平均距离和最短距离');
function DrawRoute(C,R)%%=========================================================================%% DrawRoute.m%% 画路线图的子函数%%-------------------------------------------------------------------------%% C Coordinate 节点坐标,由一个N×2的矩阵存储%% R Route 路线%%=========================================================================N=length(R);scatter(C(:,1),C(:,2));hold onplot([C(R(1),1),C(R(N),1)],[C(R(1),2),C(R(N),2)],'g')hold onfor ii=2:Nplot([C(R(ii-1),1),C(R(ii),1)],[C(R(ii-1),2),C(R(ii),2)],'g')hold onend