在研究遺傳算法的時候,隨帶看到了蟻羣算法,發現了很有意思。
進而一細想,發現還在遊戲的尋路中有一定應用的可能,首先,我們很頭大的一個問題有時候在於,對於一大羣AI,在同一幀來了一個請求,要求他們進行實時的尋路,這樣我們還要不影響幀率的話,就要保證這些AI的尋路計算在1/FPS的時間內算完,但是對於A*那樣的啓發式算法來說,還是很有壓力的。很大概率程序會直接崩掉。
蟻羣算法就具備這樣的好處——即使數據規模變大,計算規模的增大也是有限的,每一步的決策都在線性內完成。並且還有一個好處,他並不需要確定的知道目標點在哪。當然這個算法是基於概率的進化型的算法——最大的通病在於,沒法保證什麼時候完成迭代。
接着我們先來介紹一下這個算法:
首先我們會初始化一些螞蟻。
這些螞蟻的目標是找到食物搬回家,回家後再出來找食物回家..........
並且這些螞蟻具有一定的感知力,會感知到家和食物,一旦感知到周圍有食物和家,就開始攜帶信息素,並開始邊走邊釋放信息素,其他螞蟻依靠信息素逐漸迭代到家和食物的路徑上,我們就完成了尋路。
具體的尋路規則是:
螞蟻在八近鄰中如果沒有找到含有信息素的,就進行隨機尋路,該尋路具有一定的慣性,即在沒有遇到牆的時候,會有更高概率保證走原方向的傾向。
如果在周圍發現了信息素,則對八近鄰的信息素濃度進行輪盤賭,來進行決定走哪個方向,當然在發現信息素的情況下,也有小概率選擇隨機尋路,這是爲了保證不陷入局部的迭代。
具體的信息素釋放是:
在找到了家的時候,攜帶家的信息素,清空食物的信息素。在找到了食物的時候,攜帶食物的信息素,清空家的信息素。
在尋路·過程中記錄步數,螞蟻在抵達格子的同時,我們在該格子釋放信息素,濃度爲總數*步數作爲線性衰減。
信息素維護規則:
格子上的信息素會隨着時間衰減。
格子上的信息素在比較小的時候會直接清爲零。
格子上有濃度上限。
這裏首先給出Ant類的定義:
public enum NowTarget:uint
{
HOME = 0,
FOOD,
NONE
}
public enum DirctionType:uint
{
DOWN = 0,
UP,
LEFT,
RIGHT,
LEFTDOWN,
LEFTUP,
RIGHTDOWN,
RIGHTUP,
NONE
}
public class Ant
{
public Vector2 mPositionIndex;
public GameObject mAIRT;
public float mInfoFood;
public float mInfoHome;
public float mObserverDistance;
public NowTarget mNowTarget;
public Vector3 mNowPositionTarget;
public Vector2 mLastDir;
public List<Vector2> mClosedArray = new List<Vector2> ();
public void Add(Vector2 v)
{
if (!Contains (v))
mClosedArray.Add (v);
}
public bool Contains(Vector2 v)
{
//Debug.Log (mClosedArray.Contains(v).ToString());
return mClosedArray.Contains (v);
}
// public List<Vector2> runit;
}
下一篇我們給出算法的具體代碼和運行結果。