蟻群演算法原理及Matlab實現

文以載道學無止境發表於2019-09-19

蟻群演算法(AG)是一種模擬螞蟻覓食行為的模擬優化演算法,它是由義大利學者Dorigo M等人於1991年首先提出,並首先使用在解決TSP(旅行商問題)上。
之後,又系統研究了蟻群演算法的基本原理和數學模型.
蟻群演算法的基本思想:

蟻群演算法的基本原理:
1、螞蟻在路徑上釋放資訊素。

2、碰到還沒走過的路口,就隨機挑選一條路走。同時,釋放與路徑長度有關的資訊素。

3、資訊素濃度與路徑長度成反比。後來的螞蟻再次碰到該路口時,就選擇資訊素濃度較高路徑。

4、最優路徑上的資訊素濃度越來越大。

5、最終蟻群找到最優尋食路徑。


人工蟻群與真實蟻群對比:


基於TSP問題的基本蟻群演算法:


TSP求解中,假設蟻群演算法中的每隻螞蟻是具有以下特徵的簡單智慧體:

每次周遊,每隻螞蟻在其經過的支路(i,j)上都留下資訊素。

‚螞蟻選擇城市的概率與城市之間的距離和當前連線支路上所包含的資訊素餘量有關。

ƒ為了強制螞蟻進行合法的周遊,直到一次周遊完成後,才允許螞蟻遊走已訪問過的城市(這可由禁忌表來控制)。


基本蟻群的兩個過程:

(1)狀態轉移

(2)資訊素更新


(1)狀態轉移


為了避免殘留資訊素過多而淹沒啟發資訊,在每隻螞蟻走完一步或者完成對所有n個城市的遍歷(也即一個迴圈結束)後,要對殘留資訊進行更新處理。

由此,t+n時刻在路徑(i,j)上的資訊量可按如下規則進行調整: 


(2)資訊素更新模型


蟻周模型(Ant-Cycle模型)

蟻量模型(Ant-Quantity模型)

蟻密模型(Ant-Density模型)

區別:

1.蟻周模型利用的是全域性資訊,即螞蟻完成一個迴圈後更新所有路徑上的資訊素;

2.蟻量和蟻密模型利用的是區域性資訊,即螞蟻完成一步後更新路徑上的資訊素。


蟻群演算法基本流程:


蟻群演算法中主要引數的選擇:


蟻群演算法中主要引數的理想選擇如下:

國內外,對於離散域蟻群演算法的改進研究成果很多,例如自適應蟻群演算法、基於資訊素擴散的蟻群演算法等,這裡僅介紹離散域優化問題的自適應蟻群演算法。

自適應蟻群演算法:對蟻群演算法的狀態轉移概率、資訊素揮發因子、資訊量等因素採用自適應調節策略為一種基本改進思路的蟻群演算法。

自適應蟻群演算法中兩個最經典的方法:蟻群系統(AntColony System, ACS)和最大-最小蟻群系統(MAX-MINAnt System, MMAS)。

蟻群系統對基本蟻群演算法改進:

①螞蟻的狀態轉移規則不同;

②全域性更新規則不同;

③新增了對各條路徑資訊量調整的區域性更新規則

用蟻群演算法求解TSP問題:一個旅行商人要拜訪全國31個省會城市,需要選擇最短的路徑.


[plain] view plain copy
%%%一個旅行商人要拜訪全國31個省會城市,需要選擇最短的路徑%%%%  
  
  
%%%蟻群演算法解決TSP問題%%%%%%%  
  
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個省會座標  
%%————————————————————————-  
%% 主要符號說明  
%% C n個城市的座標,n×2的矩陣  
%% NC_max 最大迭代次數  
%% m 螞蟻個數  
%% Alpha 表徵資訊素重要程度的引數  
%% Beta 表徵啟發式因子重要程度的引數  
%% Rho 資訊素蒸發係數  
%% Q 資訊素增加強度係數  
%% 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);   %各代最佳路線的長度  
L_ave=zeros(NC_max,1);        %各代路線的平均長度  
  
  
  
while NC<=NC_max        %停止條件之一:達到最大迭代次數,停止  
    %%第二步:將m只螞蟻放到n個城市上  
    Randpos=[];   %隨即存取  
    for i=1:(ceil(m/n))  
        Randpos=[Randpos,randperm(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)); %找到最佳路徑(非0為真)  
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)                  %繪製第一個子圖形  
   %畫路線圖  
%%=========================================================================  
%% DrawRoute.m  
%% 畫路線圖  
%%————————————————————————-  
%% C Coordinate 節點座標,由一個N×2的矩陣儲存  
%% R Route 路線  
%%=========================================================================  
N=length(R);  
scatter(C(:,1),C(:,2));  
 hold on  
 plot([C(R(1),1),C(R(N),1)],[C(R(1),2),C(R(N),2)],’g’)  
 hold on  
for ii=2:N  
    plot([C(R(ii-1),1),C(R(ii),1)],[C(R(ii-1),2),C(R(ii),2)],’g’)  
     hold on  
end  
title(‘旅行商問題優化結果 ’)  
  
subplot(1,2,2)                  %繪製第二個子圖形  
plot(L_best)  
hold on                         %保持圖形  
plot(L_ave,’r’)  
title(‘平均距離和最短距離’)     %標題  
%%%一個旅行商人要拜訪全國31個省會城市,需要選擇最短的路徑%%%%
 
 
%%%蟻群演算法解決TSP問題%%%%%%%
 
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個省會座標
%%-------------------------------------------------------------------------
%% 主要符號說明
%% C n個城市的座標,n×2的矩陣
%% NC_max 最大迭代次數
%% m 螞蟻個數
%% Alpha 表徵資訊素重要程度的引數
%% Beta 表徵啟發式因子重要程度的引數
%% Rho 資訊素蒸發係數
%% Q 資訊素增加強度係數
%% 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);   %各代最佳路線的長度
L_ave=zeros(NC_max,1);        %各代路線的平均長度
 
 
 
while NC<=NC_max        %停止條件之一:達到最大迭代次數,停止
    %%第二步:將m只螞蟻放到n個城市上
    Randpos=[];   %隨即存取
    for i=1:(ceil(m/n))
        Randpos=[Randpos,randperm(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)); %找到最佳路徑(非0為真)
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)                  %繪製第一個子圖形
   %畫路線圖
%%=========================================================================
%% DrawRoute.m
%% 畫路線圖
%%-------------------------------------------------------------------------
%% C Coordinate 節點座標,由一個N×2的矩陣儲存
%% R Route 路線
%%=========================================================================
N=length(R);
scatter(C(:,1),C(:,2));
 hold on
 plot([C(R(1),1),C(R(N),1)],[C(R(1),2),C(R(N),2)],'g')
 hold on
for ii=2:N
    plot([C(R(ii-1),1),C(R(ii),1)],[C(R(ii-1),2),C(R(ii),2)],'g')
     hold on
end
title('旅行商問題優化結果 ')
 
subplot(1,2,2)                  %繪製第二個子圖形
plot(L_best)
hold on                         %保持圖形
plot(L_ave,'r')
title('平均距離和最短距離')     %標題
 
 
 

輸出結果如下:

        </div>
            </div>
        </article>
 
    <div class="article-bar-bottom">
            <div class="article-copyright">
        版權宣告:本文為博主原創文章,未經博主允許不得轉載。          https://blog.csdn.net/u012017783/article/details/71872950       </div>
                    <div class="tags-box artic-tag-box">
        <span class="label">文章標籤:</span>
                    <a class="tag-link" href="http://so.csdn.net/so/search/s.do?q=蟻群演算法&amp;t=blog" target="_blank">蟻群演算法                     </a>
    </div>
                    <div class="tags-box">
        <span class="label">個人分類:</span>
                    <a class="tag-link" href="https://blog.csdn.net/u012017783/article/category/6541475" target="_blank">智慧優化演算法                     </a>
    </div>
                </div>
 
<!-- !empty($pre_next_article[0]) -->
    </div>

————————————————
版權宣告:本文為CSDN博主「DemonHunter211」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/kwame211/article/details/80347593

相關文章