【國賽培訓(xùn)】蟻群算法

時間:2019.8.12
老師:祁永強(qiáng)
內(nèi)容:蟻群算法基本原理
個性:“無中生有,自圓其說”,戴準(zhǔn)帽子(套框架),優(yōu)化算法必須能用matlab仿真,狠勁,煉獄式成長,書由厚到薄(按頁)由薄到厚(),撕書式成長,佯裝努力結(jié)果是沒有差別的,為人師在于喚人醒,“日鋸其半,萬日不竭”,20頁最佳

感想:從原理上了解了蟻群算法,所找的一份ACATSP代碼成功復(fù)現(xiàn),并理解了全過程。唯獨(dú)在下一個訪問地點(diǎn)的概率計算與選擇上稍有存疑,寫在了最后。歡迎交流探討觀點(diǎn),e-mail:03170908@cumt.edu.cn

1.概述概念

起源:意大利M.Dorigo等,通過模擬自然界螞蟻搜索路徑的行為,提出的新型模擬進(jìn)化算法。
原理:螞蟻在運(yùn)動過程中,能感知信息素,指導(dǎo)自己的運(yùn)動方向(正反饋)。信息素越多越好,為什么,因?yàn)槌跏紩r,信息素越多說明往返越多(同樣時間時),即路徑最短。
核心:信息素+正反饋(所有群體算法的核心)
適用:求解TSP問題、分配問題、job-shop調(diào)度問題
優(yōu)勢:求解復(fù)雜優(yōu)化問題(特別是離散優(yōu)化問題)
比較優(yōu)勢:與大多數(shù)基于梯度的優(yōu)化算法想比
1.無集中控制約束,不會因個別的故障影響整個問題的求解,保證魯棒性
2.非直接信息交換,確保系統(tǒng)的擴(kuò)展性
3.并行分布式
4.對問題定義的連續(xù)性無特殊要求
5.算法實(shí)現(xiàn)簡單

2.蟻群算法基本思想

信息素要按一定比率揮發(fā)(避免局部最優(yōu))

每只螞蟻的一部轉(zhuǎn)移概率由圖中的每條邊上的兩類參數(shù)決定:
1.信息素值也稱信息素痕跡
2.可見度,即先驗(yàn)值

信息素的更新方式:
1 揮發(fā) :所有路徑上的信息素以一定比率進(jìn)行減少
2 增強(qiáng) :給螞蟻評價,好螞蟻加強(qiáng)

基于圖的蟻群算法(GBAS)

3.基本蟻群算法

P_{ij}^k(t)表示t時刻螞蟻k從城市i到城市j的轉(zhuǎn)移概率,計算公式如下:

P^k(i,j)=\left\{ \begin{aligned} &\frac {\tau[(i,j)]^\alpha{\cdot}{\eta}[(i,j)]^\beta}{\sum \limits_{s\in{J}_k({i})}\tau[(i,s)]^\alpha{\cdot}{\eta}[(i,s)]^\beta} & if\ j\in{J}_k(i) \\ &0& {otherwise} \end{aligned}\tag{1} \right.

{\tau[(i,j)]^\alpha} :信息素
{{\eta}[(i,j)]^\beta} : 信息素增強(qiáng)(啟發(fā)式的體現(xiàn),和距離負(fù)相關(guān))
\alpha\beta : 推薦1,5
信息素?fù)]發(fā)系數(shù)\rho:推薦0.5
信息素增強(qiáng)\delta=Q/L,Q推薦1,L表示距離長度

規(guī)模和終止條件:
1 給定終止輪數(shù)
2 最優(yōu)解了連續(xù)次相同
3 給定目標(biāo)值

4.【進(jìn)階】收斂

馬于爾科夫收斂定義,依概率收斂于1
證明收斂,才能說算法是可以實(shí)現(xiàn)的
蟻群算法分支:MAX-MIN螞蟻,精英螞蟻,蟻周算法,蟻密算法,蟻量算法

5.代碼實(shí)例

蟻群算法針對TSP應(yīng)用(超詳細(xì)分析)
ant-colony-algorithm-for-TSP(MATLAB可直接運(yùn)行代碼)
原始出處:解放軍信息工程大學(xué)老師
下面代碼注釋為本人針對上面的資料進(jìn)行學(xué)習(xí)之后添加,歡迎交流。轉(zhuǎn)移矩陣部分務(wù)必參考上面的公式

function [R_best,L_best,L_ave,Shortest_Route,Shortest_Length]=ACATSP(C,NC_max,m,Alpha,Beta,Rho,Q)
%%-------------------------------------------------------------------------
%% 主要符號說明
%% C n個城市的坐標(biāo),n×2的矩陣
%% NC_max 最大迭代次數(shù)
%% m 螞蟻個數(shù)
%% Alpha 表征信息素重要程度的參數(shù)     1
%% Beta 表征啟發(fā)式因子重要程度的參數(shù)  5
%% Rho 信息素蒸發(fā)系數(shù)                0.5
%% Q 信息素增加強(qiáng)度系數(shù)               1
%% R_best 各代最佳路線
%% L_best 各代最佳路線的長度
%%=========================================================================
 
%%第一步:變量初始化
n=size(C,1);%n表示問題的規(guī)模(城市個數(shù))
D=zeros(n,n);%D表示完全圖的賦權(quán)鄰接矩陣
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時不計算,應(yīng)該為0,但后面的啟發(fā)因子要取倒數(shù),用eps(浮點(diǎn)相對精度)表示
        end
        D(j,i)=D(i,j);   %對稱矩陣
    end
end
Eta=1./D;          %Eta為啟發(fā)因子,這里設(shè)為距離的倒數(shù)
Tau=ones(n,n);     %Tau為信息素矩陣
Tabu=zeros(m,n);   %存儲并記錄路徑的生成
NC=1;               %迭代計數(shù)器,記錄迭代次數(shù)
R_best=zeros(NC_max,n);       %各代最佳路線
L_best=inf.*ones(NC_max,1);   %各代最佳路線的長度,先賦值inf無窮大,后面更新
L_ave=zeros(NC_max,1);        %各代路線的平均長度
 
while NC<=NC_max        %停止條件之一:達(dá)到最大迭代次數(shù),停止
    %%第二步:將m只螞蟻放到n個城市上,全放完需要[m/n]輪
        Randpos=[];   %#隨機(jī)存取,此處初始起點(diǎn),可以固定設(shè)置
    for i=1:(ceil(m/n))
        Randpos=[Randpos,randperm(n)];%randperm產(chǎn)生1到n的隨機(jī)序列
    end %使用這種隨機(jī)分配方法可以保證初始去往各個城市的螞蟻數(shù)量均勻,比全部隨機(jī)要更好
    Tabu(:,1)=(Randpos(1,1:m))';    %取出前m個,賦給Tabu路徑矩陣,即給出了m只螞蟻的初始去往地點(diǎn)

    %%第三步:m只螞蟻按概率函數(shù)選擇下一座城市,對應(yīng)公式中的轉(zhuǎn)移矩陣
    for j=2:n     %所在城市不計算,j表示即將訪問的下一座城市
        for i=1:m    
            visited=Tabu(i,1:(j-1)); %記錄已訪問的城市,避免重復(fù)訪問
            J=zeros(1,(n-j+1));       %待訪問的城市,總數(shù)n-j+1
            P=J;                      %待訪問城市的選擇概率分布
            Jc=1;                     %待訪問的城市個數(shù),初始為1(用于修改矩陣J時做下標(biāo))
            for k=1:n
                if isempty(find(visited==k, 1))%這里改善了尋找的性能,只要能找到一個等于K就非空
                    J(Jc)=k;
                    Jc=Jc+1;           %待訪問的城市個數(shù)自加1
                end
            end                         %循環(huán)完成后將更新完待訪問矩陣J
            %下面計算從當(dāng)前城市visted(end)轉(zhuǎn)移到待選城市k的概率分布,參照公式的分子
            %信息素的作用也僅體現(xiàn)在這里,計算轉(zhuǎn)移矩陣概率
            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); %若計算的概率大于rand的就可以選擇這條路線
            to_visit=J(Select(1));   %選擇可選城市列表Select中的第一個作為將訪問的下一個
            Tabu(i,j)=to_visit;
        end
    end

    if NC>=2
        Tabu(1,:)=R_best(NC-1,:);  
        %NC=2開始,第一只螞蟻路徑使用上一輪的最佳路線,參與下面的信息素更新
        %#所以其實(shí)上面i=1那只螞蟻的路徑推演是沒必要的,可以用if去優(yōu)化掉
    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));      %#一輪下來后走過的距離,此處假定了最終回到起點(diǎ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;                      %迭代繼續(xù)


    %%第五步:更新信息素
    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);          
        %此次循環(huán)在路徑(i,j)上的信息素增量
        end
            Delta_Tau(Tabu(i,n),Tabu(i,1))=Delta_Tau(Tabu(i,n),Tabu(i,1))+Q/L(i);
        %#此次循環(huán)在從n會到起點(diǎn)上的信息素增量,對應(yīng)要求,單程可刪去
    end
    Tau=(1-Rho).*Tau+Delta_Tau; %考慮信息素?fù)]發(fā)掉Rho,更新后的信息素,加上Delta
    %%第六步:路徑表清零
    Tabu=zeros(m,n);             %%直到最大迭代次數(shù)
end


%%第七步:輸出結(jié)果
Pos=find(L_best==min(L_best));  %找到最佳路徑(非0為真)
Shortest_Route=R_best(Pos(1),:) %最大迭代次數(shù)后最佳路徑
Shortest_Length=L_best(Pos(1))  %最大迭代次數(shù)后最短距離

subplot(1,2,1)                  %繪制第一個子圖形
DrawRoute(C,Shortest_Route)     %畫路線圖的子函數(shù)
subplot(1,2,2)                  %繪制第二個子圖形
plot(L_best)
hold on                         %保持圖形
plot(L_ave,'r')
title('平均距離和最短距離')     %標(biāo)題

function DrawRoute(C,R)
%%=========================================================================
%% DrawRoute.m
%% 畫路線圖的子函數(shù)
%% C Coordinate 節(jié)點(diǎn)坐標(biāo),由一個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')%#這里繪制了起點(diǎn)到終點(diǎn)的直連線,非循環(huán)路徑可刪去
hold on

for i=2:N
    plot([C(R(i-1),1),C(R(i),1)],[C(R(i-1),2),C(R(i),2)],'g')
    hold on
end
title('旅行商問題優(yōu)化結(jié)果 ')

關(guān)于代碼的一點(diǎn)說明,結(jié)合蟻群算法的原理和主要的轉(zhuǎn)移概率公式,理解代碼不難。上面的代碼是針對完全圖的回路所計算的,其中有多處可以加以改動,在注釋號之后加上了#號,體現(xiàn)我的一點(diǎn)個人見解。

此外,一個困惑:上面在計算待訪問城市之后,關(guān)于下一個城市的選擇,使用的是向前累加,取判斷大于某個隨機(jī)值rand,這樣體現(xiàn)的是輪盤賭算法嗎?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容