機器學習(MACHINE LEARNING)MATLAB蟻羣算法解決TSP問題

1 蟻羣算法

基本原理:
(1)螞蟻在攜帶等量的信息素一路釋放
(2)信息素濃度會和路徑的長度成反比
(3)下次螞蟻來到該路口會選擇信息素濃度較高的那條
(4)短的路徑上的信息素濃度會越來越大,最終成爲蟻羣的最優路徑
信息素更新模型

蟻周模型(Ant-Cycle模型)

蟻量模型(Ant-Quantity模型)

蟻密模型(Ant-Density模型)

區別:

1.蟻周模型利用的是全局信息,即螞蟻完成一個循環後更新所有路徑上的信息素;

2.蟻量和蟻密模型利用的是局部信息,即螞蟻完成一步後更新路徑上的信息素。
在這裏插入圖片描述
蟻羣算法中主要參數的選擇:
在這裏插入圖片描述
蟻羣算法中主要參數的理想選擇如下:
在這裏插入圖片描述

2 蟻羣算法與TSP問題的關係

蟻羣算法就是螞蟻尋找食物的過程,而把多個食物放在不同的地方,就是著名的TSP(Traveling Salesman Problem)問題,而信息素分佈最多的路線就是最短的路徑。

3 代碼實現

項目下載地址!


[xdata,textdata]=xlsread('11.xls'); %加載10個城市的數據,數據按照表格中的位置保存在Excel文件11.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('城市縱座標'); 

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章