Excel表exp12_3_1.xls中數據為:
clc clear all [xdata,textdata]=xlsread('exp12_3_1.xls'); %加載20個城市的數據,數據按照表格中的位置保存在Excel文件exp12_3_1.xls中 x_label=xdata(:,2); %第二列為橫坐標 y_label=xdata(:,3); %第三列為縱坐標 C=[x_label y_label]; %坐標矩陣 n=size(C,1); %n表示城市個數 D=zeros(n,n); %D表示完全圖的賦權鄰接矩陣,即距離矩陣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)=0; %i=j, 則距離為0; end end end %%==================蟻群算法實現過程====================================================== %%============== 第一步 變量初始化============== iter_max=100; %最大迭代次數 m=30; % 螞蟻個數 Alpha=1; % 表征信息素重要程度的參數 Beta=5; % 表征啟發式因子重要程度的參數 Rho=0.8; % 信息素蒸發系數 Q=10; % 信息素增加強度系數 Eta=1./D; % Eta為能見度因數,這里設為距離的倒數 Tau=ones(n,n); % Tau為信息素矩陣,初始化全為1 Tabu=zeros(m,n); % 存儲並記錄路徑的生成 nC=1; % 迭代計數器 R_best=zeros(iter_max,n); %各代最短路線,行為最大迭代次數,列為城市個數 L_best=inf.*ones(iter_max,1);%%各代最短路線的長度,inf為無窮大 L_ave=zeros(iter_max,1); % 各代平均路線長度 %%============== 第二步 將m只螞蟻放到城市上============== while nC<=iter_max %停止條件之一:達到最大迭代次數 Randpos=[]; for i=1:(ceil(m/n)) %ceil表示向無窮方向取整 Randpos=[Randpos,randperm(n)]; %randperm(n):表示隨機產生一個整數排列 end Tabu(:,1)=(Randpos(1,1:m))'; %每只螞蟻(m只)都對應有一個位置,Tabu(:,1)為每只螞蟻走過的第一個城市 %% ============== 第三步 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 %利用循環求解待訪問城市,如果第k個城市不屬於已訪問城市,則其為待訪問城市 if length(find(visited==k))==0 J(Jc)=k; Jc=Jc+1; %下表加1,便於下一步存儲待訪問的城市 end end for k=1:length(J) % 下面計算待訪問城市的概率分布,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([1 2 3])=1 3 6,目的在於使得Pcum的值總有大於rand的數 Select=find(Pcum>=rand); %按概率選取下一個城市:當累積概率和大於給定的隨機數,則選擇求和被加上的最后一個城市作為即將訪問的城市 if isempty(Select) %若選擇城市為空集,則隨機將任一城市加入禁忌表中 Tabu(i,j)=round(1+(n-1)*rand); else next_visit=J(Select(1)); %next_visit表示即將訪問的城市 Tabu(i,j)=next_visit; %將訪問過的城市加入禁忌表中 end end end if nC>=2;Tabu(1,:)=R_best(nC-1,:);end %若迭代次數大於等於2,則將上一次迭代的最佳路線存入到Tabu的第一行中 %% ==============第四步 記錄本次迭代最佳路線============== L=zeros(m,1); for i=1:m; R=Tabu(i,:); for j=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(nC)=min(L); %最優路徑為距離最短的路徑 pos=find(L==L_best(nC)); %找出最優路徑對應的位置:即為哪只螞蟻 R_best(nC,:)=Tabu(pos(1),:); %確定最優路徑對應的城市順序 L_ave(nC)=mean(L); %求第k次迭代的平均距離 nC=nC+1; %% ==============第五步 更新信息素,此處蟻周系統============== Delta_Tau=zeros(n,n); %Delta_Tau(i,j)表示所有螞蟻留在第i個城市到第j個城市路徑上的信息素增量 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); 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)); %找到L_best中最小值所在的位置 Shortest_Route=R_best(Pos(1),:) %提取最短路徑 Shortest_Length=L_best(Pos(1)) %提取最短路徑長度 %% ==============作圖============== figure(1) %作迭代收斂曲線圖 x=linspace(0,iter_max,iter_max); y=L_best(:,1); plot(x,y,'-','LineWidth',2); xlabel('迭代次數'); ylabel('最短路徑長度'); figure(2) %作最短路徑圖 Shortest_Route=[Shortest_Route Shortest_Route(1)]; plot([C(Shortest_Route,1)],[C(Shortest_Route,2)],'o-'); grid on for i = 1:size(C,1) text(C(i,1),C(i,2),[' ' num2str(i)]); end xlabel('城市橫坐標'); ylabel('城市縱坐標');