基本蟻群算法-螞蟻覓食路徑的演變

UNITY3D 中進行模擬演算

???????高清完整版:http://www.acfun.cn/v/ac4623849

經過60代之后
第1代

??螞蟻在覓食過程中能夠在其經過的路徑上留下一種稱之為信息素的物質,并在覓食過程中能夠感知這種物質的強度,并指導自己的行動方向,它們總是朝著信息素強度高的方向移動,因此大量的螞蟻組成的集體覓食就表現為一種對信息素的正反饋現象。
??某一條路徑越短,路徑上經過的螞蟻就越多,其信息素遺留的也就越多,信息素的濃度也就越高,螞蟻選擇這條路的幾率也就越高,由此構成正反饋的過程,從而逐漸地逼近最優路徑,并找到最優路徑。

算法簡要流程
(1)初始化。
(2)選擇從初始節點下一步可以到達的所有節點,根據公式

計算出前往每個節點的概率。并利用賭徒輪盤選取下一步的初始點。需要注意的是螞蟻只能向四周八個節點前進。

第 k 只螞蟻從節點 i 到節點 j 的概率。
在 t 時刻,表示節點 i 至節點 j 邊上的信息激素量,各條邊的初始值為同一常數
表示 i,j 兩節點間的啟發值,與兩節點間距離成反比。
α、β 為信息素和啟發值得權重參數
網格數量,例如地圖(a)中 N=16
保存第 k 只螞蟻已行的節點。若螞蟻陷入U型障礙,使得螞蟻無后續節點選擇,則默認該螞蟻已經死亡,算法刪除該螞蟻及其所尋路徑

(3)更新路徑以及路徑長度。
(4)重復(2),(3)兩步,直到找到食物或者無路可走之后退出。
(5)重復(2),(3),(4)直到m只螞蟻全部完成旅途,一代算是結束。
(6)信息素更新。每次所有螞蟻旅行完成后對信息素進行全局更新,過去的信息素逐漸消逝,并加入新的信息素。其中沒有找到食物的螞蟻不予以計算。根據公式

揮發系數,一般取0~1之間常數
在 t+1 時刻,節點 i,j 間信息素的量
本次循環中節點 i,j 間信息素的增量
在 t 時刻,第 k 只螞蟻所尋路徑的長度

(7)重復(2)~(6),直到n代螞蟻全部完成旅行。

地圖信息

網格環境(黑色為障礙物)和行動邏輯圖
網格與序號關系圖
網格規模 N;//網格數量
螞蟻種群數量 numberOfAnts;
迭代次數 numberOfIterations;
信息素揮發系數 ρ;//一般取0~1之間常數
信息素 τ[i][j]; //留在i,j節點間信息素的量,各條邊的初始值為同一常數
信息素權重參數 α;
信息素增量 Δτ[i][j];//本次循環中節點 i,j 間信息素的增量
啟發值 η[];//計算各個網格節點到目標網格的直線距離的倒數。
啟發值權重參數 β;
禁忌表 tabu[][];//保存螞蟻已行節點。若螞蟻陷入U型障礙,使得螞蟻無后續節點選擇,
//則默認該螞蟻已經死亡,算法刪除該螞蟻及其所尋路徑
概率 p[];//前往各個節點的概率值
路徑 path[];//記錄這一代這一只螞蟻的行動路線
路徑表 PATH[][];//記錄每一代每一只螞蟻的行動路線
路徑長度 pathLeagth;//記錄這一代這一只螞蟻的行動路線的距離
路徑長度表 PATH_LEAGTH[][];//記錄每一代每一只螞蟻的行動路線的距離
起點 start;//蟻巢
終點 target;//食物

算法開始前的初始化工作和要用到的公式函數:

//直線和斜線網格之間的移動成本
BET-DISTANCE(_start, _target)
1. dstX = |_startX - _targetX|的絕對值
2. dstY = |_startY - _targetY|的絕對值
3. if dstX > dstY
4.    return 1.4 * dstY + 1 * (dstX - dstY)
5. return 1.4 * dstX + 1 * (dstY - dstX)
             
//歐幾里得距離平方。
EUCLID-DISTANCE(_startX, _startY, _targetX, _targetY)
1. dstX = |_startX - _targetX|的絕對值
2. dstY = |_startY - _targetY|的絕對值
3. return (dstX ^ 2 + dstY ^ 2) ^ 0.5

//初始化啟發式信息,計算各個網格到目標網格的直線距離的倒數。
//啟發值和直線距離成倒數,直線距離越遠啟發值越小,反之亦然。
1. s = 當前網格序號
1. for i = 0 to 網格坐標x
2.     for j = 0 to 網格坐標y
3.          if s ≠ 目標網格序號
4.              η[s - 1] = 1 / EUCLID-DISTANCE(i, j, target.i, target.j)
5.          else
6.              η[s - 1] = 999
7.          s += 1;

//初始化每條路徑上信息素的量
1. for i = 0 to N - 1
2.     for j = 0 to N - 1
3.         τ[i][j] = 1;

算法開始

1. for iteration = 1 to numberOfIterations - 1
2.     for ant = 1 to numberOfAnts - 1

3.         currentNode = start
           α= 1
           β = 8
           pathLength = 0

           //禁忌表初始化,用來記錄這一代這一只螞蟻走過的路,已經走過的路用 false 表示
4.         for i = 0 to 網格坐標x 
5.             for j = 0 to 網格坐標y
6.                 tabu[i][j] = true
7.         tabu[currentNode.x][currentNode.y] = false//起點不讓走了

           //下一步可以前往的節點
           //GetNeighbours() 見之前發表的 A*網格尋路這篇文章
8.         neighbours = GetNeighbours(currentNode);
9.         for i = 0 to neighbours.Count - 1
10.            neighbour = neighbours[i];
11.            if neighbour.不是障礙物 && tabu[neighbour.x][neighbour.y]
12.                movableRange.Add(neighbour);//可以前往的節點

           //螞蟻未遇到食物 并且 未陷入死胡同 
13.        while currentNode ≠ target && movableRange.Count >= 1

               //計算走每條路的概率
14.            for i = 0 to movableRange.Count - 1
15.                t = τ[currentNode.網格序號 - 1][movableRange[i].網格序號]- 1] ^ α
16.                e = η[movableRange[i].網格序號 - 1] ^ β
17.                p[i] = t * e
18.            psum = 0
19.            for i = 0 to p.length - 1
20.                psum = p[i] + psum
21.            for i = 0 to p.length - 1
22.                p[i] = p[i] / psum

               //用賭徒輪盤選擇下一步怎么走
23.            pcum[0] = P[0]
24.            for i = 1 to movableRange.Count - 1
25.                pcum[i] = pcum[i - 1] + p[i]
26.            pindex = 0;
27.            random = (0.0f, 1.0f)之間的隨機小數
28.            for i = 0 to movableRange.Count - 1
29.                if pcum[i] >= random
30.                    pindex = i
31.                    break
32.            nextNode = movableRange[pindex];

               //狀態更新和記錄
33.            path.Add(nextNode)
34.            pathLength = pathLength + BetDistance(currentNode, nextNode)
35.            currentNode = nextNode

               //已訪問過的節點從禁忌表中刪除           
36.            tabu[currentNode.x][currentNode.y] = false

               //下一步可以前往的節點
37.            neighbours = GetNeighbours(currentNode);
38.            for i = 0 to neighbours.Count - 1
39.                neighbour = neighbours[i];
40.                if neighbour.不是障礙物 && tabu[neighbour.x][neighbour.y]
41.                    movableRange.Add(neighbour);//可以前往的節點

42.        這里結束 while 循環

           //記下每一代每一只螞蟻的覓食路線和路線長度
43.        PATH[iteration][numberOfAnts] = path
44.        if path[path.Count - 1] == target
45.            PATH_LEAGTH[iteration][numberOfAnts] = pathLeagth
46.        else
47.            PATH_LEAGTH[iteration][numberOfAnts] = 0

48.        這里結束 for ant = 1 to numberOfAnts  遍歷

       //更新信息素
49.    for i = 0 to N - 1
50.        for j = 0 to N - 1
51.            Δτ[i][j] = 0;
52.    for i = 0 to numberOfAnts - 1
53.        if PATH_LEAGTH[iteration][i] ≠ 0
54.            pia = PATH[iteration][i]
55.            plia= PATH_LEAGTH[iteration][i]
56.            for s = 0 to pia.Count - 2
57.                x = pia[s]
58.                y = pia[s + 1]
59.                Δτ[x][y] = Δτ[x][y] + 1 / plia
60.                Δτ[y][x] = Δτ[y][x] + 1 / plia
61.    τ = (1 - ρ) * τ + Δτ//這里使用矩陣加法和乘法的原則進行計算
62. 結尾
63.
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容