蟻羣算法
蟻羣算法是一種用來尋找優化路徑的概率型算法。
它由Marco Dorigo於1992年在他的博士論文中提出,其靈感來源於螞蟻在尋找食物過程中發現路徑的行爲。
這種算法具有分佈計算、信息正反饋和啓發式搜索的特徵,本質上是進化算法中的一種啓發式全局優化算法。
一. 基本原理
- 在研究螞蟻覓食行爲過程中,人們發現,儘管單隻螞蟻的能力十分有限,但整個蟻羣卻在覓食過程中可以發現從蟻巢到食物源的最短路徑。
在覓食過程中,螞蟻通過“媒介質”來協調它們之間的行動。所謂“媒介質”指的是一種以環境的變化爲媒介的間接通信方式。螞蟻在尋找食物時,以其產生的被稱爲信息素的化學物質作爲媒介而間接的傳遞信息。當螞蟻從蟻穴走到食物源,從而形成了含有信息素的路徑。 - 蟻羣算法是對自然界螞蟻的尋徑方式進行模似而得出的一種仿生算法:螞蟻在運動過程中,能夠在它所經過的路 徑上留下信息素(pheromone)的物質進行信息傳遞,而且螞蟻在運動過程中能夠感知這種物質,並以此指導自己的運動方向。
- 由大量螞蟻組成的蟻羣集體行爲便表現出一種信息正反饋 現象:某一路徑上走過的螞蟻越多,則後來者選擇該路徑的概率就越大。
二. 算法流程
- 在ACO算法中,人工螞蟻實際上代表的是一個解的隨機構建過程,從最初的空解開始,通過不斷地向部分解添加解的成分而構建出一個完整的解。
- AS算法對TSP的求解主要有兩大步驟:
- 路徑構建
- 信息素更新
三. 實驗分析
alpha —— 信息素重要程度因子
beta —— 啓發函數重要程度因子
rho —— 信息素揮發因子
改變因子的大小:
1. beta、rho不變,alpha發生變化
alpha = 0.1,beta = 5,rho = 0.1:
最短距離:25119.2698
最短路徑:4 14 39 15 1 44 27 3 5 13 32 42 31 28 22 21 24 35 10 11 26 16 43 7 41 19 47 33 46 49 29 25 45 18 30 50 17 37 6 2 38 40 34 9 8 36 12 48 23 20 4
alpha = 1,beta = 5,rho = 0.1 :
最短距離:23965.9929
最短路徑:21 22 28 31 42 13 32 3 5 27 44 15 1 4 14 39 20 23 48 12 36 8 9 34 40 6 2 38 17 37 50 30 18 35 24 16 11 26 43 41 7 19 47 33 46 49 29 25 10 45 21
alpha = 5,beta = 5,rho = 0.1 :
最短距離:23537.0522
最短路徑:10 25 29 49 41 7 19 47 33 46 32 13 3 5 27 44 15 1 14 4 39 20 23 48 12 36 8 9 34 40 6 2 38 17 37 50 21 22 28 31 42 43 26 11 16 30 18 35 24 45 10
alpha = 10,beta = 5,rho = 0.1 :
最短距離:23830.8718
最短路徑:50 37 17 34 40 6 2 38 9 8 36 12 48 14 4 39 20 23 1 15 44 27 3 5 13 32 42 31 28 22 21 30 18 45 10 25 29 49 41 7 19 47 33 46 43 26 11 16 35 24 50
2. alpha、rho不變,beta發生變化
beta = 1,alpha = 1,rho = 0.1 :
最短距離:26355.7492
最短路徑:42 31 28 22 21 24 45 26 11 16 10 25 29 49 41 7 19 47 33 46 20 23 39 14 4 12 48 8 36 15 1 44 27 5 34 9 38 6 2 40 17 37 50 30 18 35 43 32 3 13 42
beta = 3,alpha = 1,rho = 0.1 :
最短距離:23799.9977
最短路徑:42 31 28 22 21 50 37 17 34 5 3 13 32 47 19 41 7 49 29 25 10 45 18 30 35 24 16 11 26 43 33 46 27 44 15 1 14 4 39 20 23 48 12 36 8 9 38 6 2 40 42
beta = 5,alpha = 1,rho = 0.1 :
最短距離:23496.1063
最短路徑:10 25 29 49 7 41 19 47 33 46 27 44 15 1 14 4 39 20 23 48 12 36 8 9 34 40 6 2 38 17 37 50 21 22 28 31 42 13 32 3 5 43 26 11 16 24 35 30 18 45 10
beta = 7,alpha = 1,rho = 0.1 :
最短距離:23985.6939
最短路徑:50 37 17 34 40 6 2 38 9 8 36 12 48 20 23 39 4 14 1 15 44 27 3 5 13 32 42 31 28 22 21 30 18 35 24 16 11 26 43 41 7 19 47 33 46 49 29 25 10 45 50
3. alpha、beta不變,rho發生變化
rho = 0.1,alpha = 1,beta = 5 :
最短距離:23496.1063
最短路徑:10 25 29 49 7 41 19 47 33 46 27 44 15 1 14 4 39 20 23 48 12 36 8 9 34 40 6 2 38 17 37 50 21 22 28 31 42 13 32 3 5 43 26 11 16 24 35 30 18 45 10
rho = 0.3,alpha = 1,beta = 5 :
最短距離:23621.4968
最短路徑:50 37 17 34 40 6 2 38 9 8 36 12 48 23 20 39 4 14 1 15 44 27 3 5 13 32 42 31 28 22 21 30 18 35 24 16 11 26 43 41 7 19 47 33 46 49 29 25 10 45 50
rho = 0.5,alpha = 1,beta = 5 :
最短距離:23661.8136
最短路徑:43 41 7 19 47 33 46 49 29 25 10 45 35 24 30 18 21 50 37 17 34 40 6 2 38 9 8 36 12 48 23 20 39 4 14 1 15 44 27 3 5 13 32 42 31 28 22 26 11 16 43
rho = 0.7,alpha = 1,beta = 5 :
最短距離:24099.5506
最短路徑:48 12 14 4 39 20 23 1 15 44 27 3 5 13 32 42 31 28 22 21 24 35 30 18 45 10 25 29 49 41 7 19 47 33 46 43 26 11 16 50 37 17 34 40 6 2 38 9 8 36 48
四. 實驗結論
- 當改變alpha時,隨着alpha值的增大,蟻羣更容易選擇之前走過的路徑,搜索路徑的隨機性減弱;當alpha越小時,蟻羣的搜索範圍減小,容易陷入局部最優。
- 當beta值越大,收斂速度更快,但當beta值過高時,雖然收斂速度快,但隨機性不高,容易陷入局部最優。
- 當rho的值較小時,殘留的信息素較多,導致無效的路徑繼續被搜索,;而rho的值較大時,殘留的信息素較少,蟻羣的搜索空間增大,收斂速度加快,無效的路徑雖然可以被排除搜索,但是不能保證正確路徑不會被放棄搜索,影響到最優值的搜索。
- 綜上,當alpha = 1,beta = 5,rho = 0.1時的參數是該TSP問題中較好的參數。
五. 代碼
%% 旅行商問題(TSP)優化
%% 清空環境變量
clear all
clc
%% 導入數據
load matlab.mat
%% 計算城市間相互距離
fprintf('Computing Distance Matrix... \n');
n = size(citys,1);
D = zeros(n,n);
for i = 1:n
for j = 1:n
if i ~= j
D(i,j) = sqrt(sum((citys(i,:) - citys(j,:)).^2));
else
D(i,j) = 1e-4;
end
end
end
%% 初始化參數
fprintf('Initializing Parameters... \n');
m = 50; % 螞蟻數量
alpha = 1; % 信息素重要程度因子
beta = 5; % 啓發函數重要程度因子
rho = 0.7; % 信息素揮發因子
Q = 1; % 常係數
Eta = 1./D; % 啓發函數
Tau = ones(n,n); % 信息素矩陣
Table = zeros(m,n); % 路徑記錄表
iter = 1; % 迭代次數初值
iter_max = 150; % 最大迭代次數
Route_best = zeros(iter_max,n); % 各代最佳路徑
Length_best = zeros(iter_max,1); % 各代最佳路徑的長度
Length_ave = zeros(iter_max,1); % 各代路徑的平均長度
%% 迭代尋找最佳路徑
figure;
while iter <= iter_max
fprintf('迭代第%d次\n',iter);
% 隨機產生各個螞蟻的起點城市
start = zeros(m,1);
for i = 1:m
temp = randperm(n);
start(i) = temp(1);
end
Table(:,1) = start;
% 構建解空間
citys_index = 1:n;
% 逐個螞蟻路徑選擇
for i = 1:m
% 逐個城市路徑選擇
for j = 2:n
tabu = Table(i,1:(j - 1)); % 已訪問的城市集合(禁忌表)
allow_index = ~ismember(citys_index,tabu);
allow = citys_index(allow_index); % 待訪問的城市集合
P = allow;
% 計算城市間轉移概率
for k = 1:length(allow)
P(k) = Tau(tabu(end),allow(k))^alpha * Eta(tabu(end),allow(k))^beta;
end
P = P/sum(P);
% 輪盤賭法選擇下一個訪問城市
Pc = cumsum(P);
target_index = find(Pc >= rand);
target = allow(target_index(1));
Table(i,j) = target;
end
end
% 計算各個螞蟻的路徑距離
Length = zeros(m,1);
for i = 1:m
Route = Table(i,:);
for j = 1:(n - 1)
Length(i) = Length(i) + D(Route(j),Route(j + 1));
end
Length(i) = Length(i) + D(Route(n),Route(1));
end
% 計算最短路徑距離及平均距離
if iter == 1
[min_Length,min_index] = min(Length);
Length_best(iter) = min_Length;
Length_ave(iter) = mean(Length);
Route_best(iter,:) = Table(min_index,:);
else
[min_Length,min_index] = min(Length);
Length_best(iter) = min(Length_best(iter - 1),min_Length);
Length_ave(iter) = mean(Length);
if Length_best(iter) == min_Length
Route_best(iter,:) = Table(min_index,:);
else
Route_best(iter,:) = Route_best((iter-1),:);
end
end
% 更新信息素
Delta_Tau = zeros(n,n);
% 逐個螞蟻計算
for i = 1:m
% 逐個城市計算
for j = 1:(n - 1)
Delta_Tau(Table(i,j),Table(i,j+1)) = Delta_Tau(Table(i,j),Table(i,j+1)) + Q/Length(i);
end
Delta_Tau(Table(i,n),Table(i,1)) = Delta_Tau(Table(i,n),Table(i,1)) + Q/Length(i);
end
Tau = (1-rho) * Tau + Delta_Tau;
% 迭代次數加1,清空路徑記錄表
% figure;
%最佳路徑的迭代變化過程
[Shortest_Length,index] = min(Length_best(1:iter));
Shortest_Route = Route_best(index,:);
plot([citys(Shortest_Route,1);citys(Shortest_Route(1),1)],...
[citys(Shortest_Route,2);citys(Shortest_Route(1),2)],'o-');
pause(0.3);
iter = iter + 1;
Table = zeros(m,n);
% end
end
%% 結果顯示
[Shortest_Length,index] = min(Length_best);
Shortest_Route = Route_best(index,:);
disp(['最短距離:' num2str(Shortest_Length)]);
disp(['最短路徑:' num2str([Shortest_Route Shortest_Route(1)])]);
%% 繪圖
figure(1)
plot([citys(Shortest_Route,1);citys(Shortest_Route(1),1)],...
[citys(Shortest_Route,2);citys(Shortest_Route(1),2)],'o-');
grid on
for i = 1:size(citys,1)
text(citys(i,1),citys(i,2),[' ' num2str(i)]);
end
text(citys(Shortest_Route(1),1),citys(Shortest_Route(1),2),' 起點');
text(citys(Shortest_Route(end),1),citys(Shortest_Route(end),2),' 終點');
xlabel('城市位置橫座標')
ylabel('城市位置縱座標')
title(['蟻羣算法優化路徑(最短距離:' num2str(Shortest_Length) ')'])
figure(2)
plot(1:iter_max,Length_best,'b',1:iter_max,Length_ave,'r:')
legend('最短距離','平均距離')
xlabel('迭代次數')
ylabel('距離')
title('各代最短距離與平均距離對比')