A (路徑搜尋)演算法

2021-06-23 09:31:18 字數 2449 閱讀 9527

a*演算法是路徑搜尋中的經典演算法,也是公認的最優演算法之一。

開始:搜尋區域

這裡假設有人要從a點去往b點,另外有一面牆將兩者分開。如下圖所示,綠色方塊代表a點,紅色方塊代表b點,藍色代表分開他們的牆。

圖一首先要注意的是我們這裡先將整個搜尋區域網格化,以方便路徑搜尋。這一方法將搜尋區域簡化為乙個簡單的2為陣列。陣列的每個元素代表網格上的一片區域,並且標記為可通過或不可通過兩種狀態。路徑由從a點到達b點所經過的方塊來表示。

這些點被稱為節點。之所以不直接叫方塊是因為區域可以被劃分為矩形,六邊形,等。而點也不一定是在中心,可以在邊緣或其他地方。

開始搜尋

一旦我們如上圖將搜尋區域網格化,將之轉化為可運算元量的節點,然後下一步就是找到乙個搜尋演算法找出最短路徑。我們從a點出發,搜尋遞迴周圍領域,直到到達目標點

開始搜尋的步驟如下:

1.   從a點出發並且將其放入到「候選列表」備用。候選列表就像就像是購物清單。現在上面只有一項在清單上,但我們會陸續新增。其中包含一些潛在的路徑點。基本上,這個列表包含有待確認的方塊。

2.   找到與起始點相鄰的所有可到達方塊,忽略那些牆,水等其他非法區域。將這些點加入到「候選列表」,存入方法與先前父方塊a的存入方法相同。這些父方塊會在我們進行路徑跟蹤回溯的時候派上用場。

3.   從「候選列表」中將a方塊刪除,並將其加入到「排除列表」,表明在此列表中的方塊不需要再去關注。

關於這點,如下圖所示,中間的方塊是起始點,它周圍的亮藍色邊框表明此方塊一經被加入到「排除列表」。所有在「候選列表」上的方塊都需要進一步檢查,他們的邊框呈現亮綠色。每乙個裡面都有乙個箭頭指向其父節點,這裡是起始方框。

圖2接下來,我們在選擇「候選列表」中的乙個領域然後大致上重複剛才的步驟,如下所述。然後選擇擁有最小f值的那個方塊

路徑評估

在路徑選擇是關鍵指標等式描述如下:

f = g + h 

這裡:我們的路徑正式不斷的遍歷「候選列表」並選擇最小f值的點。這個過程會在稍後詳細說明。首先來了解我們是如何計算等式的。

如上所述,g是利用先前產生的路徑到達當前點所得長度。此例中,出於簡化目的,我們定義單元格之間的距離為10,對角單元格距離為14,同時這樣做也會大大減少計算量。

有多中計算方法。這裡所使用的方法是曼哈頓方法,該方法累計從當前點到目標點在水平方向和垂直方向(忽略對角線方向)所要經過的所有方塊數,同時忽略可能遇到的障礙。然後將結果乘以10(單位距離),之所以成為曼哈頓方法,是因為這就像要數從乙個地方到另乙個地方要走過多少個街區,而同時你有不能斜穿街區。

看完這個描述,你或許會認為所謂的「啟發式」不過是將剩餘的路徑長度粗略的估計為兩點間的直線距離。事實上並非如此。我們正是在試圖估計實際剩餘距離(一般會比實際距離更長),與實際距離越接近,演算法越快速,如果估計值過大,就會有可能出現找出的路徑不是最短路徑的情況。這種情況我們稱之為「不可接受啟發式」

第一步搜尋的f,g,h可表示如下圖

4) 將其從「候選列表」中刪除加入到「排除列表」

5) 檢查其領域內方塊,排除不可通過方塊,並且將沒有在「候選列表」中的方塊加入到「候選列表」。是當前選中方塊成為父方塊。

6) 如果領域內存在方塊在「候選列表中」中,那麼就檢查是否從當前點經由那個候選方塊是一條更好路徑。換句話說,檢查那個方塊的g值是否會因為我們使用了當前點到達那裡而變小,如果不是,什麼都不做,另一方面,如果新的路徑g值變小了,就將那個候選方塊的父節點改為當前點。最後重新計算那個候選節點的f和g值

譯者注:

這一步是a*演算法較為難理解的一步,這一步的目的在於優化從起始點到候選列表中的點路徑,因為在h函式既定的情況下,候選列表中h值就是一定的,此時優化g值可以幫助找到最小的f值。

現在來看一下,在候選列表中的8個方塊中,擁有最小f值的是右邊中間的方塊,所以選擇它為下乙個方塊,在**中該方塊邊緣以藍色高亮。

圖4首先將其從「候選列表」中刪除,加入到「排除列表」。然後檢查其領域,右邊和左邊中間的方塊都被排除。

領域餘下的4個方塊都已經在「候選列表」中,所以我們需要檢查是否從當前點經由那個候選方塊是一條更好路徑。計算可以經由當前點並不能改善原有候選列表中方塊的g值。所以什麼都不做

譯者注:g是從起始點到所計算點所經過路徑點的g值的和

圖5這次,我們排除當前方塊右邊的三個方塊,至於右下那個被排除,則是這裡選擇的穿透策略導致,你也可以選擇其他的穿透策略。

重複剛才的步驟知道我們將目標嗲加入到「排除列表」,如下圖所示:

圖6那麼我們要如何來選擇路徑呢?答案很簡單,我們只要從目標點開始不斷的沿著其父方塊就可以找回到起始方塊。如圖中紅點方塊所示。

圖7現在將整個步驟總結如下:

1) 將起始點加入到「候選列表」

2) 重複如下步驟:

a) 搜尋候選列表的最小f值,將其選為當前點

b) 放入「排除列表」

c) 對於與其相鄰的8個方塊

d) 終止條件:

3)儲存路徑,從目標點開始不斷的沿著其父方塊就可以找回到起始方塊。

A 搜尋演算法

啟發式搜尋演算法 要理解 a 搜尋演算法,還得從啟發式搜尋演算法開始談起。所謂啟發式搜尋,就在於當前搜尋結點往下選擇下一步結點時,可以通過乙個啟發函式 來進行選擇,選擇代價最少的結點作為下一步搜尋結點而跳轉其上 遇到有乙個以上代價最 少的結點,不妨選距離當前搜尋點最近一次展開的搜尋點進行下一步搜尋 ...

A 搜尋演算法

a 演算法是基於bfs的一種入門級啟發式搜尋演算法,就是將bfs的佇列改為基於估價的優先佇列,可以快速地找到答案。優先隊列為小根堆 while 優先佇列不為空 取出隊頭並擴充套件 將擴充套件節點以估價值 當前值為優先順序入隊 endwhile估價函式越接近真實值演算法越優,但一定不能大於真實值,否則...

深度搜尋演算法查詢最短路徑

從圖中可以得到乙個5 5的二維矩陣,利用深度搜尋演算法,求出最短路徑。從最後的執行結果,可以直觀的看出搜尋的過程 實現如下 include pch.h include include include using namespace std define m 99999999 const int ci...