智能優化算法之蟻羣算法(1)

蟻羣算法(ant colony algorithm) : 一種模擬進化算法

螞蟻在覓食過程中能夠在其經過的路徑留下一種稱爲信息素的物質,並在覓食的過程中能感知這種物質的強度,並指導自己的行動方向,他們總是朝着該物質強度高的方向移動,因此大量螞蟻組成的集體覓食就表現爲一種對信息素的正反饋現象。(非常符合常識對吧,這就是智能優化算法的魅力)
蟻羣算法尋優的快速性是通過正反饋式的信息傳遞和積累來保證的。而算法的早熟性收斂又可以通過其分佈計算特徵加以避免。

下面介紹五種蟻羣算法的過程:(第一種較經典,後四種均爲改進方法)

  1. 螞蟻系統

     ①初始化 : 初始時刻,m只螞蟻隨機放置,(第一次迭代)各條路徑上的信息素初始值相等,設τij(t) = τ0爲信息素初始值,可設τ0 = m/Lm,Lm是由最近鄰啓發式方法構造的路徑長度。
     ②狀態轉移 : 螞蟻k(k = 1,2,...m)按照隨機比例規則選擇下一步要轉移的城市,選擇概率爲
    

在這裏插入圖片描述

τij(t) 爲邊(i,j)上的信息素;
ŋij(t)是啓發函數,表示螞蟻從i到j的期望程度,其表達式爲ŋij(t) = 1/dij,(dij爲i到j的距離);
allowedk爲螞蟻k下一步被允許訪問的點集合;
α爲信息啓發因子,反應螞蟻在運動過程中所積累的信息素在指導蟻羣搜索中的相對重要程度;
β爲期望啓發因子,反應啓發式信息在指導蟻羣搜索過程中的相對重要程度。

③禁忌表 : 爲了不讓螞蟻選擇已經訪問過的地方,採用禁忌表的形式來記錄螞蟻k當前所走過的地方。
④信息素更新 : 信息素揮發+信息素釋放
信息素更新公式如下

在這裏插入圖片描述

其中ρ爲信息素揮發因子,且ρ∈(0,1),ρ的大小直接影響到蟻羣的全局搜索能力及收斂速度。
ρ過小時,以前搜索過的路徑再次被選擇的可能性變大,容易出現局部收斂現象。
ρ過大時,算法有較強的隨機性和全局搜索能力,但搜索能力降低。

根據信息素更新策略的不同,Dorigo(蟻羣算法的提出者)曾給出三種不同的模型,分別稱爲Ant-Cycle模型、Ant-Quantity模型和Ant-Density模型其區別在於Δ τijk(t)的計
算方式不同。其中Ant-Cycle模型利用的是整體信息,及螞蟻完成一個循環(每個螞蟻都走過了所有地方)後更新所有路徑上的信息素(全局更新);
Ant-Quantity模型和Ant-Density模型則利用的是局部信息,即螞蟻完成一步後更新路徑上的信息素(局部更新)。
Ant-Cycle Δ τijk(t) = Q/Lk (Lk是第k只螞蟻的路徑長度)
Ant-Quantity Δ τijk(t) = Q/dij(dij是i到j的距離)
Ant-Density Δ τijk(t) = Q(Q爲信息素強度)

Q爲自定義數值,其作用是充分利用全局信息反饋量,使算法在正反饋機制的作用下以合理的速度找到問題最優解。Q越大,越有利於算法的快速收斂,但當Q特別大時,雖然收斂速度很快,但其全局搜索能力變差,易限於局部最優解,故其計算性能也不穩定。
在這裏插入圖片描述在這裏插入圖片描述
(摘自 任瑞春.基於排序加權的蟻羣算法[D].大連:大連海事大學,2006:16-17.)
我們上一章提過,智能優化算法具有隨機性,參數選擇依賴經驗,就應用最多的Ant-Cycle模型而言,最好的經驗結果是0≤α≤5;0≤β≤5;0.10≤ρ≤0.99;10≤Q≤10000(段海濱.蟻羣算法原理及其應用[M].北京:科學出版社,2005)

⑤螞蟻完成一次循環後,清空禁忌表,重新回到初始地點,準備下一次周遊(循環)。

爲了理解,附上解決相關問題的代碼

%%TSP旅行商問題%%
%%算法:蟻羣算法(螞蟻系統+蟻周模型)%%

%%算法介紹:
%%①初始化 :初始化 : 初始時刻,m只螞蟻隨機放置。
%%②狀態轉移 : 螞蟻k(k = 1,2,...m)按照隨機比例規則選擇下一步要轉移的城市。
%%③禁忌表 : 爲了不讓螞蟻選擇已經訪問過的地方,採用禁忌表的形式來記錄螞蟻k當前所走過的地方。
%%④信息素更新 : 信息素揮發+信息素釋放
%%⑤螞蟻完成一次循環後,清空禁忌表,重新回到初始地點,準備下一次周遊(循環)。

clear all;%清除工作區所有變量
%%常量設置(常量開頭字母大寫)
AntNum = 50;%%螞蟻數量
Alpha = 3;%%信息啓發因此α∈[0,5]   
Beta = 3;%%期望啓發因子β∈[0,5]
Rho = 0.2;%%信息素揮發因子ρ∈[0.1,0.99]
Q = 1;%%蟻周模型信息素更新公式中參數Q∈[10,10000]
IterationTimes = 300;%%迭代(iteration)次數

%%城市的(x,y)座標
Cities = [ 
    41 94;
    37 84;
    54 67;
    25 62;
    7 64;
    2 99;
    68 58;
    71 44;
    54 62;
    83 69;
    64 60;
    18 54;
    22 60;
    83 46;
    91 38;
    25 38;
    24 42;
    58 69;
    71 71;
    74 78;
    87 76;
    18 40;
    13 40;
    82 7;
    62 32;
    58 35;
    45 21;
    41 26;
    44 35;
    4 50
    ];
%%相關數據準備
CityNum = size(Cities,1);
DisMatrix = zeros(CityNum,CityNum);

bestRoute = zeros(IterationTimes,CityNum);%記錄每次迭代最佳路線(其中包含全局最優解),用於蟻周模型更新信息素
bestDistance =inf.*ones(IterationTimes,1);%記錄每次迭代最佳路線距離,用於求全局最優解,然後帶入蟻周模型信息素更新模式中的Lk 
for i = 1:CityNum
    for j = i:CityNum %%矩陣爲對稱矩陣,故j可以從i開始,然後令disMatrix(j,i) = disMatrix(i,j)即可
        if i~=j
            DisMatrix(i,j) = ((Cities(i,1)-Cities(j,1))^2+(Cities(i,2)-Cities(j,2))^2)^(1/2);
        else
            DisMatrix(i,j) = eps;
        end
        DisMatrix(j,i) = DisMatrix(i,j);
    end
end

EtaMatrix = 1./DisMatrix;%%ηij(t)啓發函數
PheromoneMatrix = ones(CityNum,CityNum);%%信息素(pheromone)矩陣(Matrix)
Tabu = zeros(AntNum,CityNum);%%禁忌表(tabu table)

%%迭代開始
for count = 1:IterationTimes
    %%①初始化 :初始化 : 初始時刻,m只螞蟻隨機放置。
    for i = 1:AntNum
        Tabu(i,1) = ceil(rand*CityNum);
    end
    %%②狀態轉移 : 螞蟻k(k = 1,2,...m)按照隨機比例規則選擇下一步要轉移的城市。
    for i = 2:CityNum
        for j = 1:AntNum
            visited = Tabu(j,1:i-1);
            P = zeros(1,CityNum);%%初始化選擇各城市的概率
            %%計算訪問各個城市的概率
            for k = 1:CityNum
                if isempty(find(visited == k,1))
                    P(k) = (PheromoneMatrix(visited(end),k)^Alpha)*(EtaMatrix(visited(end),k)^Beta);
                else
                    P(k) = 0;%%不可訪問的城市概率爲0;
                end
            end
            P = P/sum(P);
            
            P = cumsum(P);
            cityIndex = find(P>=rand);%%選擇常用方法:輪盤賭選擇法
            %%③禁忌表 : 爲了不讓螞蟻選擇已經訪問過的地方,採用禁忌表的形式來記錄螞蟻k當前所走過的地方。
            Tabu(j,i) = cityIndex(1);
        end
    end   	
     dis = zeros(AntNum,1);%%準備記錄每隻螞蟻的路線長度
    %%開始計算每隻螞蟻本次迭代路線長度
    for i = 1:AntNum
        for j = 1:CityNum-1
            dis(i) = dis(i) + DisMatrix(Tabu(i,j),Tabu(i,j+1));
        end
        dis(i) = dis(i) + DisMatrix(CityNum,1);
    end
   % 求本次迭代最優解或全局最優解在螞蟻系統中不需要
    disMin = min(dis);
    routeIndex = find(dis==disMin);
    bestRoute(count,:) = Tabu(routeIndex(1),:);
    bestDistance(count) = disMin; 
     %%④信息素更新 : 信息素揮發+信息素釋放
    deltaPhe = zeros(CityNum,CityNum);
    for i = 1:AntNum
        for j = 1:CityNum-1
            deltaPhe(Tabu(i,j),Tabu(i,j+1)) = deltaPhe(Tabu(i,j),Tabu(i,j+1)) + Q/dis(i);
        end
        deltaPhe(Tabu(i,CityNum),Tabu(i,1)) = deltaPhe(Tabu(i,CityNum),Tabu(i,1)) + Q/dis(i);%%從終點到起點
    end
     PheromoneMatrix = (1 - Rho).* PheromoneMatrix + deltaPhe;
    %%⑤螞蟻完成一次循環後,清空禁忌表,重新回到初始地點,準備下一次周遊(循環)。
    Tabu = zeros(AntNum,CityNum);
end

resultDistance =  min(bestDistance);%%求全局最優解,最短路徑距離
bestRouteIndex = find(bestDistance == resultDistance)
resultRoute = bestRoute(bestRouteIndex(1),:);%%求全局最優解,最短路徑索引

R = resultRoute;
C = Cities;
N=length(R);
scatter(C(:,1),C(:,2));
 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('旅行商問題優化結果 ');

minDis = 425.7183在這裏插入圖片描述

%%簡單路徑規劃問題%%
%%算法:蟻羣算法(螞蟻系統+蟻周模型)%%

%%算法介紹:
%%①初始化 :初始化 : 初始時刻,m只螞蟻隨機放置。在這個問題中,m只螞蟻均放在起始點。
%%②狀態轉移 : 螞蟻k(k = 1,2,...m)按照隨機比例規則選擇下一步要轉移的地點。
%%③禁忌表 : 爲了不讓螞蟻選擇已經訪問過的地方,採用禁忌表的形式來記錄螞蟻k當前所走過的地方。
%%④信息素更新 : 信息素揮發+信息素釋放
%%⑤螞蟻完成一次循環後,清空禁忌表,重新回到初始地點,準備下一次出發。

clear all;
clc;
AntNum = 50;%%螞蟻數量
Alpha = 1;%%信息啓發因此α∈[0,5]   
Beta = 3;%%期望啓發因子β∈[0,5]
Rho = 0.5;%%信息素揮發因子ρ∈[0.1,0.99]
Q = 1;%%蟻周模型信息素更新公式中參數Q∈[10,10000]
IterationTimes = 300;%%迭代(iteration)次數

%%1表示障礙物,0表示可以通過%%
Map = [0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
     0 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
     0 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
     0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
     0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
     0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
     0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
     0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 0 0 0 0 0;
     0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0;
     0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0;
     0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0;
     0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0;
     0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0; 
     0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0;
     1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0;
     1 1 1 1 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0;
     0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 1 1 0;
     0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0;
     0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0;
     0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0;
     ];
[row,column] = size(Map);
tauMatrix = ones(row*column,row*column);%%初始化信息素矩陣
%tauMatrix = 8 .* tauMatrix;
startPoint = [1,1];
finalPoint = [row,column];
D = G2D(Map);
N = size(D,1);  %%像素的個數
a = 1;    %像素邊長,用於判斷點座標
startPointX = a * (startPoint(1) - 0.5);
startPointY = a * (startPoint(2) - 0.5);
finalPointX = a * (finalPoint(1) - 0.5);
finalPointY = a * (finalPoint(2) - 0.5);

start = (startPoint(1) - 1)*column + startPoint(2);
final = (finalPoint(1) - 1)*column + finalPoint(2);

Eta = zeros(N);%%啓發信息,每個點到終點的距離的導數,螞蟻傾向於走離終點近的點
for i = 1 : N
    selfX = a * (mod(i,row) - 0.5);             %% ---------→x
    if selfX == -0.5                            %%|
        selfX = a * (row - 0.5);                %%|
    end                                         %%|
    selfY = a * (ceil(i/row) - 0.5);            %%↓ y
    if i ~= final
        Eta(i) = 1/(((selfX - finalPointX)^2 + (selfY - finalPointY)^2)^0.5);
    else
        Eta(i) = 100;
    end
end

tabuMatrix = ones(AntNum,N);  %% 1 可達, 0 不可達

routes = cell(IterationTimes,AntNum);%%記錄每次迭代每隻螞蟻的路徑
routesDistance = zeros(IterationTimes,AntNum);
minij = inf;
mini = 0;
minj = 0;
%迭代開始
for i = 1:IterationTimes
    for j = 1:AntNum
        %%①初始化 :初始化 : 初始時刻,m只螞蟻隨機放置。在這個問題中,m只螞蟻均放在起始點。
        position = start;
        path = start;%%記錄本次迭代螞蟻j的路徑
        distance = 0;%%記錄本次迭代螞蟻j的路徑距離;
        tabuMatrix(j,start) = 0;%%排除初始點
        
	%%TSP中除了禁忌表中的任意頂點都可以到達,allowedk = U - tabuk
        %%但這個問題中只有相鄰八個像素可達,故要先找出八個像素
        %%並查看他們是否在禁忌表中,若在,則將鄰接矩陣相應位置設置爲0(不可達);
        DD = D;%%每隻螞蟻有自己的一張鄰接矩陣
        DW = DD(start,:);
        
	newIndex = find(DW);
        indexLength = length(newIndex);

	while position~=final && indexLength>=1%%當螞蟻走到終點或螞蟻無路可走的時候停止循環
            p = zeros(1,indexLength);
            %%②狀態轉移 : 螞蟻k(k = 1,2,...m)按照隨機比例規則選擇下一步要轉移的地點。
            for k = 1:indexLength
                p(k) = (tauMatrix(position,newIndex(k))^Alpha + Eta(newIndex(k))^Beta);
            end
            p = p./sum(p);
            %%輪盤賭選擇法
            p = cumsum(p);
            toVisitIndex = find(p>=rand);
            toVisit = newIndex(toVisitIndex(1));
            %%記錄路徑並移動到下一個點
            path = [path,toVisit];
            distance = distance + DD(position,toVisit);
            position = toVisit;
            %%重新尋找可到達區域
            DW = D(position,:);
            index = find(DW);
            %%③禁忌表 : 爲了不讓螞蟻選擇已經訪問過的地方,採用禁忌表的形式來記錄螞蟻k當前所走過的地方。
            for c = 1:length(index)
                if tabuMatrix(j,index(c)) == 0
                    %DD(position,index(k)) = 0;
                    %DD(index(k),position) = 0;
                    DW(index(c)) = 0;
                end
            end
            tabuMatrix(j,position) = 0;
            newIndex = find(DW);
            indexLength = length(newIndex);
        end
        %%此時螞蟻已經走到終點或走到死角
        %%記錄本次迭代螞蟻j的路徑
        routes{i,j} = path;
        if path(end) == final
            routesDistance(i,j) = distance;
            if distance < minij
                mini = i;
                minj = j;
                minij = distance;
            end
        else
            routesDistance(i,j) = 0;
        end
    end
    %%此時每隻螞蟻都走完了,完成了一次迭代
    %%④信息素更新 : 信息素揮發+信息素釋放(蟻周模型)
    if mini~=0&&minj~=0%%如果存在有到達終點的路徑
        delta = zeros(row*column,row*column);
        rout = routes{mini,minj};
        count = length(rout) - 1;
        L = routesDistance(mini,minj);
        for s = 1:count
            x = rout(s);
            y = rout(s+1);
            delta(x,y) = Q/L;
            delta(y,x) = Q/L;
        end
    tauMatrix = (1 - Rho).* tauMatrix + delta;
    end
%%⑤螞蟻完成一次循環後,清空禁忌表,重新回到初始地點,準備下一次出發。
    tabuMatrix = ones(AntNum,N);
end

%%繪製爬行圖
figure(1)
axis([0,row,0,column]);
for i = 1:row
    for j = 1:column
        if Map(i,j)==1
            x1 = j - 1;y1 = row - i;
            x2 = j;y2 = row - i;
            x3 = j;y3 = row - i + 1;
            x4 = j - 1;y4 = row - i + 1;
            fill([x1,x2,x3,x4],[y1,y2,y3,y4],[0.2,0.2,0.2]);
            hold on
        else
            x1 = j - 1;y1 = row - i;
            x2 = j;y2 = row - i;
            x3 = j;y3 = row - i + 1;
            x4 = j - 1;y4 = row - i + 1;
            fill([x1,x2,x3,x4],[y1,y2,y3,y4],[1,1,1]);
            hold on
        end
    end
end
title('機器人運動軌跡');
xlabel('座標x');
ylabel('座標y');
routLength = length(rout);
rx = rout;
ry = rout;
for i = 1:routLength
    rx(i) = a *(mod(rout(i),row) - 0.5);
    if rx(i) == -0.5
        rx(i) = a * (row - 0.5);
    end
    ry(i) = a*(row + 0.5 - ceil(rout(i)/row));
end
plot(rx,ry);
bestDistance = routesDistance(mini,minj);

%%由圖生成row^2個像素與row^2個像素的鄰接矩陣
function D = G2D(G) 
    [row,column] = size(G);
    D = zeros(row*column,row*column);
    for i = 1:row
        for j = 1:column
            if G(i,j)==0 %%此點不是障礙物
                %%遍歷整個圖row^column個像素,尋找與他八聯通的八個像素
                for m = 1:row
                    for n = 1:column
                        if G(m,n)==0 %%如果像素不是障礙物
                            im = abs(i - m);
                            jn = abs(j - n);
                            if im+jn==1||(im==1&&jn==1)  %%如果在上下左右和斜着的八個方向
                         %%則設置鄰接矩陣的權值
                            D((i - 1) * row + j,(m - 1) * row + n) = (im + jn)^0.5;
                            end
                        end
                    end
                end
            end
        end
    end
end

當解決有障礙物的路徑規劃問題上,我一開始出現了
在這裏插入圖片描述
這種一看就不對的圖像,最終我觀察發現解收斂太快,於是我減小了Q的值,從1000變爲了1,最終便有了良好的結果。
在這裏插入圖片描述
大量仿真實驗發現,螞蟻系統在解決小規模TSP問題時性能尚可,能較快的發現最優解,但隨着測試問題規模的擴大,螞蟻系統算法的性能下降的比較嚴重,容易出現停滯現象,因此出現了針對其缺點的改進算法。
在智能優化算法之蟻羣算法(2)中詳細講解
2. 精英螞蟻系統
3. 最大-最小螞蟻系統
4. 基於排序的蟻羣算法
5. 蟻羣系統

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章