一、蟻群算法簡介
蟻群算法是對自然界螞蟻的尋徑方式進行模似而得出的一種仿生算法:螞蟻在運動過程中,能夠在它所經過的路徑上留下信息素(pheromone)的物質進行信息傳遞,而且螞蟻在運動過程中能夠感知這種物質,並以此指導自己的運動方向。由大量螞蟻組成的蟻群集體行為便表現出一種信息正反饋現象:某一路徑上走過的螞蟻越多,則后來者選擇該路徑的概率就越大。蟻群算法具有分布計算、信息正反饋和啟發式搜索的特征,本質上是進化算法中的一種啟發式全局優化算法。
二、TSP問題(旅行商問題)
T S P 問 題 可 以 用 一 個 帶 權 完 全 圖G=(N,A)來表示,其中N是帶有n=|N|點(城市)的集合,A是完全連接這些點的邊的集合。每一條邊(i,j)屬於A都帶有一個權值,它代表城市i與城市j之間的距離。TSP問題就是要找到圖中的最短哈密爾頓回路。
1、構建圖:構建圖與問題描述圖是一致的,成份的集合C對應着點的集合(即:C=N),連接對應着邊的集合(即L=A),且每一條邊都帶有一個權值,代表點i和j之間的距離。
2、約束條件:所有城市都要被訪問且每個城市最多只能被訪問一次。
3、信息素和啟發式信息:TSP 問題中的信息素表示在訪問城市i后直接訪問城市j的期望度。啟發式信息值一般與城市i和城市j的距離成反比。
4、解的構建:每只螞蟻最初都從隨機選擇出來的城市出發,每經過一次迭代螞蟻就向解中添加一個還沒有訪問過的城市。當所有城市都被螞蟻訪問過之后,解的構建就終止。
三、實現流程及偽代碼
四、代碼實現
隨機生成50個城市進行測試,初始螞蟻數量為50,信息素重要程度因子alpha = 1,啟發函數重要程度因子beta = 5,信息素揮發因子rho = 0.1,最大迭代次數為150
%% 旅行商問題(TSP)優化 %% 清空環境變量 clear all clc %% 導入數據 %load citys_data.mat city = ceil(rand(50,2) * 5000) load city.mat %% 計算城市間相互距離 fprintf('Computing Distance Matrix... \n'); n = size(city,1); D = zeros(n,n); for i = 1:n for j = 1:n if i ~= j D(i,j) = sqrt(sum((city(i,:) - city(j,:)).^2)); else D(i,j) = 1e-4; end end end %% 初始化參數 fprintf('Initializing Parameters... \n'); m = 50; % 螞蟻數量 alpha = 1; % 信息素重要程度因子 beta = 5; % 啟發函數重要程度因子 rho = 0.1; % 信息素揮發因子 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; % 構建解空間 city_index = 1:n; % 逐個螞蟻路徑選擇 for i = 1:m % 逐個城市路徑選擇 for j = 2:n tabu = Table(i,1:(j - 1)); % 已訪問的城市集合(禁忌表) allow_index = ~ismember(city_index,tabu); allow = city_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([city(Shortest_Route,1);city(Shortest_Route(1),1)],... [city(Shortest_Route,2);city(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([city(Shortest_Route,1);city(Shortest_Route(1),1)],... [city(Shortest_Route,2);city(Shortest_Route(1),2)],'o-'); grid on for i = 1:size(city,1) text(city(i,1),city(i,2),[' ' num2str(i)]); end text(city(Shortest_Route(1),1),city(Shortest_Route(1),2),' 起點'); text(city(Shortest_Route(end),1),city(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('各代最短距離與平均距離對比')
五、實驗結果:
5.1隨機生成的50個城市坐標
實驗數據1:螞蟻數量為50,信息素重要程度因子alpha = 1,啟發函數重要程度因子beta = 5,信息素揮發因子rho = 0.1,最大迭代次數為150
實驗數據2:其他數據不變,信息素揮發因子rho = 0.5
實驗數據3:其他數據不變,啟發函數重要程度因子beta = 3,
實驗數據4:其他數據不變,啟發函數重要程度因子beta = 7
實驗數據5:其他數據不變,信息素重要程度因子alpha = 4
六、結果分析與總結
1、 螞蟻數量、信息素重要程度因子、啟發函數重要程度因子beta、最大迭代次數相同時,rho=0.1與rho=0.5
rho=0.1時,城市序列的起點為39,終點為46。在最短距離的迭代中,迭代次數約為10時,各代的最短距離趨於平緩。當將信息素揮發因子調整為0.5時,可以發現當信息素增大后,最短距離變小,迭代次數約為40時,各代的最短距離就已經趨於平緩。雖然信息素的揮發速度越來越快,但是尋找到的最短路徑反而比之前的更短,當rho過小時,未被選中的路徑上的信息素量將迅速衰減,容易陷入局部最優,算法的收斂性加大。另外,當rho過大時,被選中的路徑上的信息素量增量減小,搜索空間變大,這樣算法雖然陷入局部最優的可能性減小,但是算法的收斂性降低。
2、Bete=5與Bete=3、bete=7
當其他因素不變,bete改為3時,發現最短距離變小,且城市序列的起點為9,終點為33。bete=5時,在最短距離的迭代中,在大概10代的時候有一個急劇的減少。但在bete=3時沒有極具的下降。在bete=7,迭代過程中開始時就趨於平緩。bete的值反映了啟發式信息在指導螞蟻搜索過程中的重要程度。Bete過小,蟻群陷入隨機搜索,就很難找到最優解。Bete過大,螞蟻在某個局部點上選擇局部最短路徑的可能性也就越大,但蟻群搜索最優路徑的隨機性就減弱,容易陷入局部最優。
3、alpha=1與alpha=4
當alpha=1時,在最短距離的迭代中,迭代次數約為10時,各代的最短距離趨於平緩。當alpha=4時,城市序列起點是7,終點是24,最短距離有所增大,但各代的最短距離的迭代趨勢和alpha=1時差不多。迭代次數在40-55之間時,平均距離有急劇下降的現象而后逐漸趨於平緩。所以,alpha的值越大,螞蟻選擇以前走過的路徑的可能性就越大,搜索的隨機性就減弱,算法也會早收斂。