# A-star algorithm, A*
# pqueue.py, available in ruiaf.org
from pqueue import heap,container
from math import sqrt
#('city',[('city1','distancebytrain'),.....],(coordx,coordy))
# don't mind city positioning too much :)
edges = [('Lisbon',[('Madrid',4),('Paris',12)],(0,0)),
('Madrid',[('Athens',12),('Berlin',15)],(2,2)),
('Athens',[('Moscow',2)],(8,10)),
('Paris',[('Berlin',5)],(5,5)),
('Berlin',[('Budapest',8),('Warsaw',6)],(6,7)),
('Budapest',[('Moscow',8)],(5,10)),
('Warsaw',[('Moscow',4)],(7,11)),
('Moscow',[],(8,11))]
node_list = {}
node_coord = {}
graph = {}
for (node,con,coord) in edges:
node_list[node]=None
node_coord[node]=coord
graph[node]=dict()
for (node,connections,coord) in edges:
for (con,weight) in connections:
graph[node][con]=weight
graph[con][node]=weight
# has to be a lower bownder for the distance
# we are using euclidean because the graph was made
# taking that into account
# if this heuristic returns 0, it's dykstra algorithm!
def heuristic(node1,node2):
#return 0
difx = node_coord[node1][0]-node_coord[node2][0]
dify = node_coord[node1][0]-node_coord[node2][0]
return sqrt(difx*difx+dify*dify)
def astar(startpoint,endpoint):
pq = heap()
node = container()
node.value = 0
node.distance = 0
node.key = startpoint
node.previous_node = None
pq.append(node)
while not pq.isempty():
node = pq.pop()
if node_list[node.key]!=None:
#we have already checked this node, move along!
#it could be possible to avoid this by cross-referencing
#the nodes and the pqueue elements, updating the values there
#then only a percolateup would be needed instead of
#adding several times the same element to the pq
continue
node_list[node.key]=(node.previous_node,node.distance)
if node.key==endpoint:
break
for child_node in graph[node.key].keys():
child = container()
child.key = child_node
child.distance = graph[node.key][child_node]+node.distance
child.value = child.distance+heuristic(child.key,endpoint)
child.previous_node = node.key
pq.append(child)
astar('Lisbon','Moscow')
for node in node_list.keys():
print node, node_list[node]