A*搜尋演算法(python)
先了解一下什麼是A*演算法。
A搜尋演算法,俗稱A星演算法。這是一種在圖形平面上,有多個節點的路徑,求出最低透過成本的演算法。常用於遊戲中的NPC(Non-Player-ControlledCharacter)的移動計算,或線上遊戲的BOT(ROBOT)的移動計算上。該演算法像Dijkstra演算法一樣,可以找到一條最短路徑;也像BFS一樣,進行啟發式的搜尋。
A演算法是一種啟發式搜尋演算法,啟發式搜尋就是在狀態空間中的搜尋對每一個搜尋的位置進行評估,得到最好的位置,再從這個位置進行搜尋直到目標。這樣可以省略大量無謂的搜尋路徑,提高了效率。
A星演算法核心公式:
F = G + H
F - 方塊的總移動代價
G - 開始點到當前方塊的移動代價
H - 當前方塊到結束點的預估移動代價
G值是怎麼計算的?
假設現在我們在某一格子,鄰近有8個格子可走,當我們往上、下、左、右這4個格子走時,移動代價為10;當往左上、左下、右上、右下這4個格子走時,移動代價為14;即走斜線的移動代價為走直線的1.4倍。
這就是G值最基本的計算方式,適用於大多數2.5Drpg頁遊。
根據遊戲需要,G值的計算可以進行擴充。如加上地形因素對尋路的影響。格子地形不同,那麼選擇透過不同地形格子,移動代價肯定不同。同一段路,平地地形和丘陵地形,雖然都可以走,但平地地形顯然更易走。
我們可以給不同地形賦予不同代價因子,來體現出G值的差異。如給平地地形設定代價因子為1,丘陵地形為2,在移動代價相同情況下,平地地形的G值更低,演算法就會傾向選擇G值更小的平地地形。
擴充公式:
G = 移動代價 * 代價因子
H值是如何預估出來的?
很顯然,在只知道當前點,結束點,不知道這兩者的路徑情況下,我們無法精確地確定H值大小,所以只能進行預估。
有多種方式可以預估H值,如曼哈頓距離、歐式距離、對角線估價,最常用最簡單的方法就是使用曼哈頓距離進行預估:
H = 當前方塊到結束點的水平距離 + 當前方塊到結束點的垂直距離
題外話:A星演算法之所以被認為是具有啟發策略的演算法,在於其可透過預估H值,降低走彎路的可能性,更容易找到一條更短的路徑。其他不具有啟發策略的演算法,沒有做預估處理,只是窮舉出所有可通行路徑,然後從中挑選一條最短的路徑。這也是A星演算法效率更高的原因。
鑑於前人已經把原理講的很清楚了,便不再廢話,想要深入瞭解下的可以參考下面的兩篇文章。
接下來上程式碼:
程式碼1
檔案AStar.py
# coding=utf-8#描述AStar演算法中的節點資料 class Point: """docstring for point""" def __init__(self, x = 0, y = 0): self.x = x self.y = y class Node: def __init__(self, point, g = 0, h = 0): self.point = point #自己的座標 self.father = None #父節點 self.g = g #g值 self.h = h #h值 """ 估價公式:曼哈頓演算法 """ def manhattan(self, endNode): self.h = (abs(endNode.point.x - self.point.x) + abs(endNode.point.y - self.point.y))*10 def setG(self, g): self.g = g def setFather(self, node): self.father = nodeclass AStar: """ A* 演算法 python 2.7 """ def __init__(self, map2d, startNode, endNode): """ map2d: 尋路陣列 startNode: 尋路起點 endNode: 尋路終點 """ #開放列表 self.openList = [] #封閉列表 self.closeList = [] #地圖資料 self.map2d = map2d #起點 self.startNode = startNode #終點 self.endNode = endNode #當前處理的節點 self.currentNode = startNode #最後生成的路徑 self.pathlist = []; return; def getMinFNode(self): """ 獲得openlist中F值最小的節點 """ nodeTemp = self.openList[0] for node in self.openList: if node.g + node.h檔案2
檔案map2d.py
# coding=utf-8from __future__ import print_functionclass map2d: """ 地圖資料 """ def __init__(self): self.data = [list("####################"), list("#*****#************#"), list("#*****#*****#*####*#"), list("#*########*##******#"), list("#*****#*****######*#"), list("#*****#####*#******#"), list("####**#*****#*######"), list("#*****#**#**#**#***#"), list("#**#*****#**#****#*#"), list("####################")] self.w = 20 self.h = 10 self.passTag = '*' self.pathTag = 'o' def showMap(self): for x in xrange(0, self.h): for y in xrange(0, self.w): print(self.data[x][y], end='') print(" ") return; def setMap(self, point): self.data[point.x][point.y] = self.pathTag return; def isPass(self, point): if (point.x self.h - 1) or (point.y self.w - 1): return False; if self.data[point.x][point.y] == self.passTag: return True;檔案3
檔案AStarTest.py
# coding=utf-8import map2dimport AStarif __name__ == '__main__': ##構建地圖 mapTest = map2d.map2d(); mapTest.showMap(); ##構建A* aStar = AStar.AStar(mapTest, AStar.Node(AStar.Point(1,1)), AStar.Node(AStar.Point(8,18))) print "A* start:" ##開始尋路 if aStar.start(): aStar.setMap(); mapTest.showMap(); else: print "no way"在AStar.py中增加了對拐角的處理,設定拐角無法直達。
執行結果:
image.png
參考:
作者:漫步_9378
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1600/viewspace-2810719/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python之 常用查詢演算法:最小項搜尋、順序搜尋、二分搜尋Python演算法
- A*搜尋演算法概述演算法
- 搜尋演算法合集 - By DijkstraPhoenix演算法
- 搜尋演算法總結演算法
- 演算法總結--搜尋演算法
- python 寫的搜尋引擎Python
- Sunday搜尋演算法實現演算法
- 啟發式搜尋的方式(深度優先,廣度優先)和 搜尋方法(Dijkstra‘s演算法,代價一致搜尋,貪心搜尋 ,A星搜尋)演算法
- 隱含波動率模型-增量搜尋演算法-python實現模型演算法Python
- Python資料結構與演算法_第6節_排序 & 搜尋Python資料結構演算法排序
- BM搜尋演算法C實現演算法
- 【演算法】深度優先搜尋(DFS)演算法
- 004.02 各類搜尋的演算法演算法
- elasticsearch演算法之搜尋模型(一)Elasticsearch演算法模型
- 0基礎學演算法 搜尋篇第一講 深度優先搜尋演算法
- 基本演算法——深度優先搜尋(DFS)和廣度優先搜尋(BFS)演算法
- Python教程:Python如何實現窮舉搜尋?Python
- python 寫的搜尋引擎 - 原始碼Python原始碼
- Python如何實現窮舉搜尋?Python
- 演算法篇 - 二叉搜尋樹演算法
- 【LeetCode】初級演算法:排序和搜尋LeetCode演算法排序
- 6.1 KMP演算法搜尋機器碼KMP演算法機器碼
- 高階搜尋演算法之迭代加深演算法
- python 二叉樹深度優先搜尋和廣度優先搜尋Python二叉樹
- 圖的廣度優先搜尋和深度優先搜尋Python實現Python
- 最佳路徑搜尋(二):啟發式搜尋(代價一致搜尋(Dijkstra search),貪心搜尋,A*搜尋)
- Python演算法練習--把搜尋樹轉成雙向連結串列Python演算法
- 0演算法基礎學演算法 搜尋篇第二講 BFS廣度優先搜尋的思想演算法
- 海量資料搜尋---搜尋引擎
- 排名演算法(二)--淘寶搜尋排序演算法分析演算法排序
- [譯] Swift 演算法學院 - KMP 字串搜尋演算法Swift演算法KMP字串
- 搜尋
- [Python手撕]搜尋二維矩陣Python矩陣
- 搜狗搜尋微信Python爬蟲案例Python爬蟲
- 深度和廣度優先搜尋演算法演算法
- 深度優先搜尋演算法(DFS)講解演算法
- JAVA圖搜尋演算法之DFS-BFSJava演算法
- 演算法筆記(廣度優先搜尋)演算法筆記