基本蟻羣算法(matlab代碼)

蟻羣算法
1991年,意大利學者M. Dorigo、V. Maniezzo和A. Colorni研究蟻羣行爲特徵,提出一種模擬蟻羣的進化算法,其算法原理基於正反饋機制或增強型學習系統,它通過信息素強度的變化,選擇最優路徑,最後收斂於最優路徑結果。
1.1蟻羣算法的基本原理
蟻羣算法是一種智能仿生算法,用來求解最優問題,其中主要解決旅行商問題(TSP)。蟻羣算法整體分爲兩個過程,包括狀態轉移和信息素更新。其基本原理如下:
① 在爬行過程中,每隻螞蟻在自身經過的支路(i,j)上都留下信息素;
② 遇見沒走過的岔路口,隨機選擇路徑,同時釋放信息素,路徑越長,濃度越短;
③ 後來的螞蟻選擇信息素濃度較高的路徑;
④ 直到所有路徑走過後,才允許螞蟻重複之前的路徑;
⑤ 最優路徑上,信息素濃度會越來越大;
⑥ 最終整個蟻羣尋得最優路徑。
1.1.1. 狀態轉移
爲了避免殘留信息素過多導致啓發信息無效,在每隻螞蟻走完一步後,要對狀態進行更新。在t時刻螞蟻k從節點i轉移到可行節點j的狀態轉移概率公式爲:
在這裏插入圖片描述
式中,在這裏插入圖片描述 爲啓發函數,一般爲距離倒數,表示螞蟻從節點i轉移到j的期望程度。t時刻節點i與節點j連接路徑上的信息素濃度爲 在這裏插入圖片描述。 alpha爲信息啓發式因子,其值越大,信息素的濃度在轉移中起的作用越大; beta爲期望啓發式因子,其值越大,啓發函數在轉移中的作用越大,即螞蟻會以較大的概率轉移到距離短的節點。
1.1.2. 信息素更新
信息素的更新分爲蟻周模型(Ant-Cycle model),蟻量模型(Ant-Quantity model)和蟻密模型(Ant-Density model)。其區別在於:
① 蟻周模型在一個螞蟻完成循環後,更新所有路徑上的信息素;
② 蟻量和蟻密模型利用的是局部信息,即螞蟻完成一步後更新路徑上的信息素。
(1)蟻周模型的信息素更新
利用全局信息,在螞蟻完成一次路徑搜索後,對所有路徑的信息素濃度進行更新,即
在這裏插入圖片描述
式中, 在這裏插入圖片描述表示第k只螞蟻在節點i與節點j連接路徑上釋放的信息素濃度; 在這裏插入圖片描述表示所有螞蟻在節點i與節點j連接路徑上釋放的信息素濃度之和。Q表示信息素強度(常值),表示螞蟻信息素總量;Lk 爲第 k只螞蟻經過的路徑長度,與搜索路徑有關,和具體路徑無關。 p表示信息素的揮發程度。
1.1.3. 蟻羣算法主要參數選取
在這裏插入圖片描述
選擇蟻羣算法最優組合參數的有效方法步驟:
① 確定螞蟻數目 ,根據節點規模/螞蟻數目≈1.5來確定大概的螞蟻數目;
② 參數粗調,即調整信息啓發式因子 、期望啓發式因子 和信息素強度Q等參數;
③ 參數微調,即調整信息揮發因子 。

%                         蟻羣算法解決航跡規劃問題
% 輸入: 
%       x_start,y_start    起始點座標 
%       x_end,y_end        	目標點座標
% 輸出: 
%       Shortest_Route      蟻羣算法生成的最航跡節點
%       Shortest_Length    	最優航跡長度
%       Shortest_J          最優航跡代價
% 功能說明:採用蟻羣算法尋找最優航跡
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [Shortest_Route,Shortest_Length,Shortest_J]=Aco(x_start,x_end,y_start,y_end,weight)
NC_max=200;							%最大循環次數
Na=10;								%螞蟻總數
Alpha=1;                            %信息啓發式因子
Beta=0.8;                           %期望啓發式因子
Rho=0.1;                            %信息揮發因子
Q=1;                                 %信息素強度
n_set=11;                           %柵格取值集合
n_grid=6;                           %起始點與目標點之間的柵格數
Eta=1./weight;                     
%啓發函數,這裏設爲各柵格點威脅代價的倒數
Tau=ones(n_set,n_set,n_grid-1); %Tau爲信息素矩陣
Tabu=zeros(Na,n_grid);            %存儲並記錄路徑的生成
NC=1;                                 %循環計數器
R_best=zeros(NC_max,n_grid);     %每次循環的最佳路線
L_best=inf.*ones(NC_max,1);      %每次循環的最佳路線的長度
L_ave=zeros(NC_max,1);            %每次循環的路線的平均長度
b=0:5:50;
while NC<=NC_max                    %判斷是否達到最大循環次數
Randpos=[];                      
%將Na只螞蟻放到第一步位置上,位置隨機產生
    for i=1:(ceil(Na/n_set))
        Randpos=[Randpos,5*randperm(10)];
    end
    for i=1:Na
        Tabu(i,1)=Randpos(i);
    end
    for j=2:n_grid                       %Na只螞蟻按概率函數選擇下一個點
        for i=1:Na      
                visited=Tabu(i,1:(j-1));  %已訪問的點
                J=Jj{j};                   	 %待訪問的點
                P=J;                          %待訪問點的選擇概率分佈              
                for k=1:length(J)           %計算待選點的概率分佈           
                 P(k)=(Tau(visited(end)/5+1,J(k)/5+1,j-1)^Alpha)*(Eta(visited(end)/5+1,J(k)/5+1)^Beta);     
%(信息素^信息啓發式因子)*(啓發函數^期望啓發式因子)
                end            
                P=P/(sum(P));                %歸一化
                Pcum=cumsum(P);              %對概率累加求和
                Select=find(Pcum>=rand);   
%若計算的概率大於原來的概率則選擇當前路線
                to_visit=J(Select(1));     %選擇下一步柵格點
                while (abs(to_visit-visited(end))>10)
                    Select=find(Pcum>=rand);
                    to_visit=J(Select(1));
                end
                Tabu(i,j)=to_visit;
        end
    end
    if NC>=2
        Tabu(1,:)=R_best(NC-1,:);           
%把上次迭代結果即最短路徑序列放在本次路徑序列中
    end
    L_l=zeros(Na,1);                          %記錄本次迭代最佳路線
    L_t=zeros(Na,1);
    for i=1:Na
        R=Tabu(i,:);
        for j=1:(n_grid-1)
                L_l(i)=L_l(i)+sqrt(25+(R(j)-R(j+1))^2);         
%第i只螞蟻走的路程
        end
        L_l(i)=L_l(i)+sqrt((x_start-5)^2+(y_start-R(1))^2)+sqrt((x_end-30)^2+(y_end-R(end))^2);
        L(i)=0.5*L_l(i)+0.5*L_t(i);         %一輪下來後走過的距離
    end
    L_best(NC)=min(L);                        %第NC次迭代的最短路徑
    pos=find(L==L_best(NC));
    Li_best(NC)=L_l(pos(1));
    R_best(NC,:)=Tabu(pos(1),:);            %第NC次迭代的最短路徑序列
    NC=NC+1;                                    %循環繼續
    Delta_Tau=zeros(n_set,n_set,n_grid-1);%更新信息素
    for i=1:Na
        for j=1:(n_grid-1)
                 					  %此次循環在路徑(i,j)上的信息素增量Delta_Tau(Tabu(i,j)/5+1,Tabu(i,j+1)/5+1,j)=Delta_Tau(Tabu(i,j)/5+1,Tabu(i,j+1)/5+1,j)+Q/L(i);                                    
        end
    end
Tau=(1-Rho).*Tau+Delta_Tau;             
%考慮信息素揮發,更新後的信息素
    Tabu=zeros(Na,n_grid);                  %禁忌表清零、結束標誌表清零
end
Pos=find(L_best==min(L_best));            %找到最佳路徑(非0爲真)
Shortest_Route=R_best(Pos(1),:);          %最大迭代次數後最佳路徑
Shortest_Length=Li_best(Pos(1));          %最大迭代次數後最短距離
Shortest_J=L_best(Pos(1));


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