蟻羣算法
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));