蟻羣算法

前言:本篇文章主要講述蟻羣算法以及相關算法的matlab實現

1、蟻羣算法html

        蟻羣算法是在20世紀90年代由澳大利亞學者Marco Dorigo等人經過觀察蟻羣覓食的過程,發現衆多螞蟻在尋找食物的過程當中,總能找到一條從螞蟻巢穴到食物源之間的最短路徑。隨後他們在螞蟻巢穴到食物源之間設置了一個障礙,一段時間之後發現螞蟻又從新走出了一條到食物源最短的路徑。經過對這種現象的不斷研究,最後提出了蟻羣算法。蟻羣算法在解決旅行商問題(即TSP問題)時,取得了比較理想的結果。算法

​                                                               

2、基本人工蟻羣算法原理優化

       當螞蟻外出尋找食物或者返回到巢穴時候,都會釋放一種特殊的信息素來標示進行的軌跡,有了這種信息傳遞機制,螞蟻才能順利的返回,進一步研究發現,這種信息素不只能被統同一個蟻羣的其餘螞蟻感覺到,並且其強度也能被其餘螞蟻所感知到,螞蟻會傾向於向信息素濃度高的路徑移動,而在移動的過程當中又會留下新的信息素。這樣,通過螞蟻越多的路徑其信息素濃度也會愈來愈高,最後,幾乎全部的螞蟻都會走信息素濃度最高的城市,就會在螞蟻巢穴與食物源之間造成一條最短的取食路徑。M.Dorigo將真實蟻羣的這種行爲抽象爲人工蟻羣算法,在一方面將真實蟻羣中最重要的信息機制賦予給了人工蟻羣,另外一方面讓人工蟻羣具有了真實蟻羣所不具有的一些其餘特徵。spa

       運用人工蟻羣算法求解TSP問題時的基本原理是:將m個螞蟻隨機地放在多個城市,讓這些螞蟻從所在的城市出發,n步(一個螞蟻從一個城市到另一個城市爲1步)以後返回到出發的城市。若是m個螞蟻所走出的m條路經對應的中最短者不是TSP問題的最短路程,則重複這一過程,直至尋找到滿意的TSP問題的最短路徑爲止。爲了說明這一個算法下面用一個算法流程圖來表示一下:.net

​                                                                       

                                                        

3、人工蟻羣算法的數學模型3d

(一)算法的相關參數code

在算法中用到的變量比較多,而每一個變量的對算法最終收斂的結果影響程度也不同,在這裏把一些重要的參數說明一下。htm

\tau _{ij} :城市i和城市j之間邊e_{ij}上信息素的殘留強度blog

\Delta\tau _{ij}:一次循環後邊e_{ij}上信息素的增量get

\Delta \tau_{ij}^{k}:一次循環以後螞蟻k對邊e_{ij}上信息素的貢獻量

\eta _{ij}:城市i,j之間的能見度,反映了由城市i轉移到城市j的啓發程度

d_{ij}:城市i到城市j之間的距離

p_{ij}^{k}:螞蟻k從當前所在的城市到下一個城市去的機率

tabu(k):禁忌表,用於存放第k只螞蟻已經走過的城市

Q:信息素總量,信息素總信息量爲螞蟻循環一週後向通過路徑釋放信息素的總量

\rho:信息素殘留係數,因爲螞蟻釋放的信息量回隨着時間的轉移而逐漸揮發,以致於路徑上的信息素不能無限遞增,該係數過小時會下降算法的全局搜素能力,過大時容易使算法陷入局部最優,影響全局搜素能力。

m:螞蟻總數,在TSP問題中,每次循環當中,每隻螞蟻所走出的每條路徑爲TSP問題的候選解,m只螞蟻一次循環所走出來的m條路經爲TSP問題的一個解子集,因此這個解子集越大則算法的全局搜索能力越強,可是過大會使算法的收斂速度下降。若是m過小的話,算法也很容易就陷入局部最優,過早的出現停滯現象,(ps:王老師講過曾經見到一個學生在論文中讓一個螞蟻去跑路徑,老師開玩笑說,估計把這隻螞蟻就給累死了)因此選擇合理的螞蟻總數是很是重要的。

 \alpha:信息啓發因子,反映了螞蟻在從城市i向城市j移動時,這兩個城市之間道路上所累積的信息素在指導螞蟻選擇城市j的程度,即蟻羣在路徑搜素中隨即性因素做用的強度。

\beta:指望值啓發式因子,反映了螞蟻在從城市i向城市j轉移時候指望值\eta _{ij}在指導蟻羣搜素中的相對重要程度。其大小反映了蟻羣在道路搜素中的先驗性、肯定性等因素的強弱,\alpha\beta的大小也會影響算法的收斂性。

 (二) 算法過程當中的關鍵步驟

一、上面講了螞蟻在選擇下一個要轉移的城市時候是基於機率選擇的,固然這個機率不是隨機機率,而是其中的一些參數來決定。假定在t時刻,螞蟻從目前所在的i城市要選擇轉移去的下一個j城市,機率大小爲p_{ij}^{k}

                                  p_{ij}^{k}(t)=\left\{\begin{matrix} & \frac{\tau_{ij}^{k}\eta _{ij}^{\beta }}{\sum_{s\in allowed_{k}}\tau_{is}^{k}(t)\eta_{is}^{\beta}(t)} &j\in allowed_{k} \\ \\ &0 &otherwise \end{matrix}\right.

其中allowed_{k}表示容許螞蟻k下一步可允許去的城市的集合,\tau_{ij}^{\alpha}爲邊e_{ij}上的信息素因數,\eta_{ij}^{\beta}爲城市i,j間能見度因數。至於這個過程具體是怎麼實現的,在程序中會有相關的源碼。

二、對任意兩個城市i,j之間道路對應的邊e_{ij}信息素增量按照下式進行:

                                                \left\{\begin{matrix} &\tau_{ij}(t+1)=\rho\tau_{ij}(t)+\Delta \tau_{ij}(t,t+1)\\ \\&\Delta\tau_{ij}(t,t+1)=\Sigma_{k=1}^{m}\Delta\tau_{ij}^{k}(t,t+1) \end{matrix}\right.

其中,\Delta\tau_{ij}^{k}(t,t+1)爲螞蟻k對邊e_{ij}上所貢獻的信息素增量,\Delta\tau_{ij}(t,t+1)是通過邊e_{ij}的全部螞蟻對邊e_{ij}的信息素量貢獻,\rho爲信息素殘留係數。對於\Delta\tau_{ij}^{k}(t,t+1)的調整方式不一樣,能夠將蟻羣算法分爲三種模型:蟻密模型、蟻量模型和蟻周模型。

 2.1 蟻密模型

   在蟻密模型當中,每一隻螞蟻在通過城市i,j時,對該邊e_{ij}所貢獻的信息素增量爲常量,每一個單位長度是Q:

                                         \Delta\tau_{ij}^{k}(t,t+1)=\left\{\begin{matrix} &Q & e_{ij}\\ &0 & otherwise \end{matrix}\right

 2.2 蟻量模型

   在蟻量模型中,一隻螞蟻k在通過城市i,j之間邊e_{ij}時,對該邊所貢獻的信息素增量爲變量,即每單位長度上爲Q/d_{ij},它與城市i,j之間的路徑長度d_{ij}有關,具體爲:

                                        \Delta\tau_{ij}^{k}(t,t+1)=\left\{\begin{matrix} &Q/d_{ij} &e_{ij}\\ & 0 & otherwise \end{matrix}\right

2.3 蟻周模型

   上述兩種模型,對兩城市之間邊e_{ij}上信息素貢獻的增量在螞蟻k通過邊的同時完成,而蟻周模型對邊e_{ij}信息素的增量是在本次循環結束時才進行更新調整。一隻螞蟻在通過城市i,j時對邊e_{ij}上貢獻的增量爲每單位長度Q/L_{k}L_{k}爲螞蟻在本次循環走出路徑的長度。

                                        \Delta\tau_{ij}^{k}(t,t+1)=\left\{\begin{matrix} &Q/L_{k} &e_{ij}\\ &0 &otherwise \end{matrix}\right

 本文章就是基於蟻周模型來實現的,介紹完上述的幾個關鍵步驟之後,就要用matlab來實現了。

4、算法的matlab實現

下面給出了matlab實現代碼,其中的註釋都是本身看懂了以後加上的,

 

%算法的第一步是先初始化 clear m=50;                                   %螞蟻總數 alpha=1;                                %信息度啓發因子 beta=2;                                 %指望值啓發式因子 Rho=0.6;                                %信息素揮發因子 NC_max=100;                             %最大循環次數 Q=80;                                   %信息素增量 C=[5.326,2.558; 4.276,3.452; 4.819,2.624; 3.165,2.457; 0.915,3.921; 4.637,6.026; 1.524,2.261; 3.447,2.111; 3.548,3.665; 2.649,2.556; 4.399,1.194; 4.660,2.949; 1.479,4.440; 5.036,0.244; 2.830,3.140; 1.072,3.454; 5.845,6.203; 0.194,1.767; 1.660,2.395; 2.682,6.072];%20個城市 % 初始化 n=size(C,1);                            %表示n個城市 D=zeros(n,n); 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; end % D(j,i)=D(i,j); end end Eta=1./D;                               %城市與城市之間的能見度,在基於機率轉移時用到這個參數 Nc=1;                                   %循環計數器 Tau=ones(n,n);                          %信息素濃度矩陣——n*n的單位陣 Tabu=zeros(m,n);                        %禁忌表  ——m*n的零陣 Road_best=zeros(NC_max,n);              %每次循環最佳路徑 最大循環次數*n個城市零陣 Roadlength_best=inf.*ones(NC_max,1);    %每次循環最佳路徑的長度  最大循環次數*1 單位陣 Roadlength_ave=zeros(NC_max,1);         %每次循環的路徑的平均值 %將螞蟻隨機分佈在n個城市 while Nc<=NC_max                        %小於最大循環次數就繼續執行 randpos=[]; for i=1:(ceil(m/n))                 %分多少次將螞蟻分佈完 randpos=[randpos,randperm(n)];  %循環產生的是20個城市的隨機數,都在一行 end Tabu(:,1)=(randpos(1,1:m));         %取前m個城市編號 %每隻螞蟻基於機率選擇轉移去下一個j城市 for j=2:n                           %從第二個城市開始選擇 for i=1:m visited=Tabu(i,1:(j-1));    %表示已經通過的城市,初始化是出發城市 J=zeros(1,(n-j+1));         %存放尚未通過的城市  1*19.....1 零陣 P=J; Jc=1; for k=1:n if length(find(visited==k))==0  %查找已經通過的城市裏面有沒有k J(Jc)=k;            %沒有的話,就把城市k記錄進未通過城市矩陣裏面 Jc=Jc+1; end end %計算待選城市的機率 for k=1:length(J) P(k)=(Tau(visited(end),J(k))^alpha)*(Eta(visited(end),J(k))^beta); %目前通過的城市到下一個全部城市的機率大小 end P=P/sum(P); %按照機率選取下一個城市 Pcum=cumsum(P); select=find(Pcum>=rand); to_visit=J(select(1)); Tabu(i,j)=to_visit; end end if Nc>=2 Tabu(1,:)=Road_best(Nc-1,:); end %記錄本次迭代最佳路線 L=zeros(m,1); for i=1:m R=Tabu(i,:);                      %第一隻螞蟻的路線賦給矩陣R 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 Roadlength_best(Nc)=min(L);           %本次循環的全部路徑中的最短路徑放在Roadlength_best中 pos=find(L==Roadlength_best(Nc));     %找出最短路徑的全部螞蟻 Road_best(Nc,:)=Tabu(pos(1),:);       %只取第一隻螞蟻的路徑 Roadlength_ave(Nc)=mean(L);           %本次循環全部路徑的平均值 Nc=Nc+1; % 跟新信息素 delta_Tau=zeros(n,n); 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,j),Tabu(i,j+1))+Q/L(i); end Tau=(1-Rho).*Tau+delta_Tau;          %這裏運用的是蟻周模型 % 禁忌表清零 Tabu=zeros(m,n); end pos=find(Roadlength_best==min(Roadlength_best)); shortest_route=Road_best(pos(1),:); shortest_length=Roadlength_best(pos(1)); figure(1) subplot(1,2,1) % subplot(1,2,1) N=length(R); scatter(C(:,1),C(:,2)); hold on plot([C(shortest_route(N),1),C(shortest_route(1),1)],[C(shortest_route(N),2),C(shortest_route(1),2)],'g'); hold on for ii=2:N plot([C(shortest_route(ii-1),1),C(shortest_route(ii),1)],[C(shortest_route(ii-1),2),C(shortest_route(ii),2)],'g'); hold on end grid on title('TSP問題優化結果'); xlabel('x') ylabel('y') subplot(1,2,2) plot(Roadlength_best) hold on plot(Roadlength_ave) grid on title('平均距離與最短距離') legend('Roadlength\_best','Roadlength\_ave') xlabel('cycle-index') ylabel('length')

 

通過100次循環,對20個城市求最優路徑,結果是23.70,執行以後的效果圖以下:

                        

5、參考文獻

[1] 李人厚,王拓. 智能控制理論和方法[M]. 西安電子科技大學出版社, 1999.

[2] https://blog.csdn.net/zuochao_2013/article/details/71872950

[3] https://zhidao.baidu.com/question/96740995.html

相關文章
相關標籤/搜索