蟻羣算法(ACA , Ant Colony Algorithm)
1 算法背景
蟻羣算法是由Marco Dorigo於1992年在他的博士論文中提出,其靈感來源於螞蟻在尋找食物過程中發現路徑的行爲。蟻羣算法是一種用來尋找優化路徑的概率型算法,本質上是進化算法中的一種啓發式全局優化算法。
在螞蟻覓食的過程中,單個螞蟻行爲比較簡單,你可能發現不了什麼特別的,但是整個蟻羣的行爲卻整體體現出了一些智能。蟻羣可以在不同的環境中,尋找到最短到達食物源的路徑。在找食物的過程中,螞蟻會在走過的路徑中釋放一種“信息素”的物質,用來標識自己的行走路徑,螞蟻具有感知能力,會沿着信息素濃度高的路徑行走。而每個螞蟻走過都會釋放信息素,這也就是一種正反饋機制,信息素越濃,走的螞蟻越多,走的螞蟻越多,信息素越濃,最後整個蟻羣都會沿着最短的路徑尋找食物。
2 算法思想
蟻羣算法的基本思想就是選擇信息素濃度最大的路徑走,碰到還沒走過的路,就隨機挑選一條路走。用螞蟻行走的路徑表示待優化問題的可行解,整個螞蟻羣體的所有路徑構成待優化問題的解空間。我們可以理解爲螞蟻的信息素含量在一次覓食過程中是一定量的,路徑越長,信息素的含量濃度越小,路徑越短,信息素的濃度越大。隨着時間的推移以及正反聵機制,路徑最短的信息素濃度會越來越大,最終整個蟻羣都會集中到最佳的路徑上,也就是待優化問題的最優解。
3 算法步驟
蟻羣算法的步驟可以歸納爲:
(1)對相關參數進行初始化;
(2)隨機將螞蟻放於不同出發點,對每個螞蟻計算其下個訪問城市,直到有螞蟻訪問完所有城市。
(3)計算各螞蟻經過的路徑長度,記錄當前迭代次數最優解,同時對路徑上的信息素濃度進行更新。
(4)判斷是否達到最大迭代次數,若否,返回步驟2;是,結束程序。
(5)輸出結果,並根據需要輸出尋優過程中的相關指標。
算法流程圖如下:
4 算法應用
蟻羣算法主要用來解決路徑規劃等離散優化問題,如調度問題、旅行商問題等。下面以旅行商問題爲例,進行詳細的介紹:
旅行商問題即TSP問題(Travelling Salesman Problem,TSP)又譯爲旅行推銷員問題、貨郎擔問題,是數學領域中著名問題之一。
TSP問題:假設有一個旅行商人要拜訪n個城市,需選擇一條路線,要求所有城市走一遍回到起點,同時使所走路程最短。
(可以提取出來關鍵信息:每個結點只能走一次;所有結點必須經過;最短路徑;最後回到起點)
5 算法實現
解決的問題:一個旅行商人要拜訪全國31個省會城市,需要選擇最短一條路線,要求所有城市走一遍回到起點。以座標的形式記錄城市的位置數據。
使用蟻羣算法,用matlab實現TSP問題代碼如下:
%% 解決的問題:一個旅行商人要拜訪全國31個省會城市,需要選擇最短的路徑
clear all;
close all;
clc ;
%% 第一步:變量初始化
m=50; % m 螞蟻個數
Alpha=1; % Alpha表徵信息素重要程度的參數
Beta=5; %Beta表徵啓發式因子重要程度的參數
Rho=0.1; % Rho信息素蒸發係數
NC_max=200; %最大迭代次數
Q=100; %信息素增加強度係數
C=[
1304 2312;
3639 1315;
4177 2244;
3712 1399;
3488 1535;
3326 1556;
3238 1229;
4196 1004;
4312 790;
4386 570;
3007 1970;
2562 1756;
2788 1491;
2381 1676;
1332 695;
3715 1678;
3918 2179;
4061 2370;
3780 2212;
3676 2578;
4029 2838;
4263 2931;
3429 1908;
3507 2367;
3394 2643;
3439 3201;
2935 3240;
3140 3550;
2545 2357;
2778 2826;
2370 2975
]; %31個省會座標數據
% R_best 各代最佳路線
% L_best 各代最佳路線的長度
n=size(C,1);%n個城市
D=zeros(n,n);%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)=eps; %i=j時不計算,應該爲0,但後面的啓發因子要取倒數,用eps(浮點相對精度)表示
end
D(j,i)=D(i,j); %對稱矩陣
end
end
%% 變量
Eta=1./D; %Eta爲啓發因子,這裏設爲距離的倒數
Tau=ones(n,n); %Tau爲信息素矩陣
Tabu=zeros(m,n); %存儲並記錄路徑的生成
NC=1; %迭代計數器,記錄迭代次數
R_best=zeros(NC_max,n); %各代最佳路線
L_best=inf.*ones(NC_max,1); %各代最佳路線的長度 %inf 正無窮
L_ave=zeros(NC_max,1); %各代路線的平均長度
%% 進行蟻羣算法
while NC<=NC_max
%第二步:將m只螞蟻放到n個城市上
Randpos=[]; %隨即存取
for i=1:(ceil(m/n))
Randpos=[Randpos,randperm(n)];%randperm(n)產生1-n的隨機數
end
Tabu(:,1)=(Randpos(1,1:m))'; %將路徑矩陣裏面的第一列隨機初始到一個城市
%第三步: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
if length(find(visited==k))==0 %開始時置0
J(Jc)=k;
Jc=Jc+1; %訪問的城市個數自加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); %cumsum,元素累加即求和
Select=find(Pcum>=rand); %若計算的概率大於原來的就選擇這條路線
to_visit=J(Select(1));
Tabu(i,j)=to_visit;
end
end
if NC>=2
Tabu(1,:)=R_best(NC-1,:);
end
%第四步:記錄本次迭代最佳路線
L=zeros(m,1); %開始距離爲0,m*1的列向量
for i=1:m
R=Tabu(i,:);
for j=1:(n-1)
L(i)=L(i)+D(R(j),R(j+1)); %原距離加上第j個城市到第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); %此輪迭代後的平均距離
NC=NC+1; %迭代繼續
%第五步:更新信息素
Delta_Tau=zeros(n,n); %開始時信息素爲n*n的0矩陣
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);
%此次循環在路徑(i,j)上的信息素增量
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)); %找到最佳路徑
Shortest_Route=R_best(Pos(1),:) %最大迭代次數後最佳路徑
Shortest_Length=L_best(Pos(1)) %最大迭代次數後最短距離
figure(1)
plot(L_best)
xlabel('迭代次數')
ylabel('最短路徑長度')
title('每代最短路徑長度進化曲線')
figure(2)
%繪製第一個子圖形,路線圖
subplot(1,2,1)
N=length(Shortest_Route);
scatter(C(:,1),C(:,2)); %繪製閃點圖
hold on
plot([C(Shortest_Route(1),1),C(Shortest_Route(N),1)],[C(Shortest_Route(1),2),C(Shortest_Route(N),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
title('旅行商最短路線結果圖 ')
%繪製第二個子圖形
subplot(1,2,2)
plot(L_best)
hold on %保持圖形
plot(L_ave,'r')
legend('最短距離','平均距離')
title('平均距離和最短距離') %標題
實驗結果如圖:
6 算法優缺點
優點:
- 正反饋,可以較快發現較好解
- 啓發式搜索,反映了搜索中的先驗性、確定性因素的強度
- 魯棒性強,不易受個體影響
缺點:
- 需要較長搜索時間
- 容易出現停滯現象
7 算法改進
蟻羣算法的改進可以從以下方面進行考慮:
(1)搜索速度改進,引入偵察蟻、工蟻。
(2)搜索策略改進,加入擾動、添加牽引力引導螞蟻朝全局最優搜索。