我正在接近探路者算法的世界,所以我开始玩两个最着名的A *和Dijkstra。
我正在使用Python开发算法,图形是字典词典:
{Node:{(Node1:weights1),(Node2:weights2),..}
我的空间是640x480
的棋盘,这些是可以遵循的所有可能路径:
这是我对算法的实现:
def Manhattan(node1, node2):
j1 = node1%640
i1 = (node1-j1)/640
j2 = node2%640
i2 = (node2-j2)/640
return np.abs(j1-j2) + np.abs(i1-i2)
def Astar(graph, start, end):
A = [None] * (640*480)
queue = [(0, 0, start, ())]
while queue:
fscore, path_len, v, sortPath = heappop(queue)
sortPath = (v, sortPath)
if v == end : break
for w, edge_len in graph[v].items():
new_cost = path_len+edge_len
if A[w] is None or new_cost < A[w]:
A[w] = new_cost
heappush(queue, (new_cost + Manhattan(w,end), new_cost, w, sortPath))
# to give same result as original, assign zero distance to unreachable vertices
return [0 if x is None else x for x in A],sortPath
def Dijkstra(graph, start, end=None):
A = [None] * (640*480)
queue = [(0, start, ())]
while queue:
path_len, v, sortPath = heappop(queue)
sortPath = (v, sortPath)
if v == end : break
if A[v] is None: # v is unvisited
A[v] = path_len
for w, edge_len in graph[v].items():
if A[w] is None:
heappush(queue, (path_len + edge_len, w, sortPath))
# to give same result as original, assign zero distance to unreachable vertices
return [0 if x is None else x for x in A],sortPath
据我所知,A *算法(如果启发函数有意义;我使用曼哈顿,因为它不可能进入对角线)应该比Dijkstra更快,因为它应该避免扩展不感兴趣的节点。
在我的情况下,Dijkstra在0.28 s
中运行而在1 s
中运行A *。两种算法的探索节点完全相同:
的Dijkstra:
A *:
我是否对A *实施做错了什么?运行时间的差异,应该是因为启发式函数我每次都从线性索引转换为矩阵行,列?任何帮助是极大的赞赏!