JS算法之A*(A星)尋路算法


今天寫一個連連看的游戲的時候,接觸到了一些尋路算法,我就大概講講其中的A*算法。

這個是我學習后的一點個人理解,有錯誤歡迎各位看官指正。

尋路模式主要有三種:廣度游戲搜索、深度優先搜索和啟發式搜索。

廣度優先搜索(Breadth First Search):又稱為"寬度優先搜索"或"橫向優先搜索",簡稱BFS。

BFS的搜索模式是:從圖中某節點v出發,在訪問了v之后依次訪問v的各個未曾訪問過的鄰接點,然后分別從這些鄰接點出發依次訪問它們的鄰接點,並使得先被訪問的節點的鄰接點先於后被訪問的節點的鄰接點被訪問,直至圖中所有已被訪問的節點的鄰接點都被訪問到。如果此時圖中尚有節點未被訪問,則需要另選一個未曾被訪問過的節點作為新的起始點,重復上述過程,直至圖中所有節點都被訪問到為止。

就像這張圖,節點1先訪問完他相鄰的節點2 3 4 5,然后再訪問先被訪問的節點2,直至節點2的相鄰點都被訪問完了再接着訪問節點4(中間會判斷節點3有沒有相鄰點)。

image

深度優先搜索(Depth First Search):簡稱DFS。

DFS的搜索模式是:從某個節點v出發,首先訪問該節點,然后依次從它的各個未被訪問的鄰接點出發深度優先搜索遍歷圖,直至圖中所有和v有路徑相通的節點都被訪問到。 若此時尚有其他節點未被訪問到,則另選一個未被訪問的節點作起始點,重復上述過程,直至圖中所有節點都被訪問到為止。 深度優先搜索是一個遞歸的過程。

以這圖為例,訪問順序是圖中的標號。

img

啟發式搜索:啟發式搜索就是在狀態空間中的訪問對每一個訪問的位置進行評估,得到最好的位置,再從這個位置進行訪問直到目標。啟發式算法有很多,例如蟻群算法、遺傳算法和模擬退火算法等,其中A*尋路算法就屬於啟發式算法。

A*估價函數

A*算法最重要的就是他的A*估價函數,用來評估哪個節點離目標點最近,用f(n) = g(n) + h(n)來表示。

f(n)是n節點的估價函數;
g(n)是初始點到n節點的實際代價;
h(n)是n節點到目標點的實際代價;

實際代價可以簡單理解為兩節點的距離(不同的場景實際代價所表示的意義有所不同)。

估價算法根據各自的需求有很多種,計算距離的估價算法主要的就是曼哈頓算法、幾何算法和對角算法。

//曼哈頓估價法
private function manhattan(node:Node):Number
{
    return Math.abs(node.x - _endNode.x) * _straightCost + Math.abs(node.y + _endNode.y) * _straightCost;
}
 
//幾何估價法
private function euclidian(node:Node):Number
{
    var dx:Number=node.x - _endNode.x;
    var dy:Number=node.y - _endNode.y;
    return Math.sqrt(dx * dx + dy * dy) * _straightCost;
}
 
//對角線估價法
private function diagonal(node:Node):Number
{
    var dx:Number=Math.abs(node.x - _endNode.x);
    var dy:Number=Math.abs(node.y - _endNode.y);
    var diag:Number=Math.min(dx, dy);
    var straight:Number=dx + dy;
    return _diagCost * diag + _straightCost * (straight - 2 * diag);
}

img

曼哈頓算法是根據網格走直線,直到目標點所在的水平或垂直平行就拐彎;

幾何算法實際上就是通過勾股定理,計算兩點間的直線距離;

對角算法結合了以上二種算法,先按對角線走,一直走到與目標點水平或垂直平行后,再筆直的走。

Open和Closed列表

open列表:用來記錄當前節點所有可能訪問的節點;

closed列表:用來記錄估價后被否決掉的節點,以后就不用再對這些節點估價了;

工作原理

有了上面基本認識后,現在大概介紹一下A*算法的工作原理。

  1. 把與當前節點相鄰的節點加入到open列表(若非起始結點,則不包括被上一個節點加入到closed列表的節點);
  2. 算出open列表里所有節點的估價函數f(n)值(總實際代價),得出最小的節點並移動到該節點,還原(清空)open列表;
  3. 把第2步否決掉的節點記錄到closed列表中;

這樣就選出了在與當前節點相鄰的節點中,離目標節點最近的節點,然后重復123步驟,直到下一個節點為目標節點。

參考文章

[Unity] A-Star(A星)尋路算法

圖的遍歷之 深度優先搜索和廣度優先搜索


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM