I'm approaching the world of pathfinder algorithms so I have started playing with the two most famous A* and Dijkstra.
I'm developing algorithms in Python and the graph is a dictionary of dictionary:
{Node:{(Node1:weights1),(Node2:weights2),..}
My space is a chessboard of 640x480
and these are all the possible paths that it is possible to follow:
This is my implementation of the algorithms:
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
As far as I know, the A* algorithm (if the heuristic function makes sense; I have used Manhattan because it is not possible to go in diagonal) should be faster than Dijkstra because it should avoid expanding the not interesting nodes.
In my case Dijkstra runs in 0.28 s
while A* in 1 s
. And the explored nodes for both the algorithms are exactly the same:
Dijkstra:
A*:
Am I doing something wrong with the A* implementation? The difference in the running time, should it be because for the heuristic function I convert each time from linear index to matrix row, column? Any help is greatly appreciated!