Python3 趣味系列題7(續) ------ A*演算法獲取迷宮最優路徑

maze.jpg
前文: Python3 趣味系列題7 ------ Prim演算法生成完美迷宮
一、A*演算法
尋找路徑的演算法有很多,例如BFS演算法、Dijkstra演算法等。BFS演算法可以在較短時間內尋找到從起點到結束點的路徑,但不一定是最優的。而Dijkstra演算法從起點開始向外圍逐漸擴充套件,直到達到結束點,因此得到的路徑一定是最優的,但是耗時較長。A*演算法可以看作這2個演算法的結合,這主要依賴於A*演算法的啟發式搜尋策略,下一步去往的網格是下面式子中具有最小值的網格:
F = G + H
- G: 代表從起始點網格到當前這個網格距離的代價;
- H:從當前這個網格到結束點網格距離的代價;
下面舉例說明:前一個到達的網格假設為A,從這個網格可以去的網格有C1, C2,C3。然後計算這3個網格中F的值最小的網格作為下一個要去的網格。當不考慮G時,演算法就變為BFS;當不考慮H時,演算法就變為Dijkstra演算法。注意上面的H只是理論上的代價值,因為實際中可能存在障礙點,這一點並不妨礙演算法的進行。
網格之間的距離可以根據網格的移動方式定義,例如只可以上下左右的移動,一般就考慮曼哈頓距離,例如本文。可以8個方向移動的,可以在斜的方向上考慮歐式距離等。
下面給出A*演算法具體的步驟:
A. 把起始點網格加入 open list ;迴圈如下過程:
- 遍歷 open list ,查詢其中 F 值最小的網格,把它作為當前要處理的網格C;
- 把網格C移到 close list;
- 獲得這個網格經過一步移動可以去的網格列表;
- 遍歷這個列表中的網格D;
- 如果網格D不在open list中,把它加入open list,並且把當前方格C設定為它的父輩網格,並存儲網格D的F值;
- 如果D已經在 open list 中,說明之前已經到達過網格D。那就需要比較以前的路徑和當前的路徑哪條路徑是最優的,也就是F值最小的。也就是得到當前的F值和之前的F值中較小的。如果是以前的小,則不需要任何操作。如果是當前的F值較小,則就把網格D的父輩網格變為當前的網格C,並且儲存網格D的F值。
B. 當終點在open list中,表明路徑已經找到了,或者open list是空的,此時沒有路徑,退出迴圈。
C. 儲存路徑。從終點網格開始,沿著父輩網格移動直至起點網格,得到最終的路徑。
二、路徑展示
- 遍歷牆的迷宮

image

image
- 遍歷網格的迷宮

image

image
點選 獲得更多趣味謎題。歡迎Follow,感謝Star!!! 掃描關注微信公眾號 pythonfan ,獲取更多。

image

image