Welcome, guest | Sign In | My Account | Store | Cart
# Dijkstra Shortest Path Algorithm
# http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
# FB - 201110296
from heapq import heappush, heappop # for priority queue
pq = []

class node:
    label = ''
    # adjacency list of the node 
    neighbors = [] # list of nodes
    distances = [] # distances to neighbors
    # for Dijkstra
    prevNode = None
    totalDistance = float('Inf')
    visited = False
    # constructor
    def __init__(self, label):
        self.label = label
        self.neighbors = []
        self.distances = []
        self.prevNode = None
        self.totalDistance = float('Inf')
        self.visited = False


# find the shortest paths to all nodes recursively
def dijkstra(node):
    # visit all neighbors and update them if necessary
    for i in range(len(node.neighbors)):
        n = node.neighbors[i]
        d = node.distances[i]
        if n.totalDistance > d + node.totalDistance:
            n.prevNode = node
            n.totalDistance = d + node.totalDistance
            heappush(pq, (n.totalDistance, n))
    node.visited = True

    (d, ne) = heappop(pq)
    if not ne.visited:
        dijkstra(ne)

# get the shortest path to the given node
def route(endNode):
    node = endNode
    labels = [endNode.label]
    # distances = []
    while node.label != node.prevNode.label:
        # distances.append(node.totalDistance - node.prevNode.totalDistance)
        node = node.prevNode
        labels.append(node.label)
    labels.reverse()
    return labels
    # distances.reverse()
    # return (labels, distances)
        
# create a graph
a = node('a')
b = node('b')
c = node('c')
d = node('d')
e = node('e')
f = node('f')
graph = (a, b, c, d, e, f)

# create bidirectional edges of the graph
edges = []
edges.append((b, c, 3))
edges.append((d, e, 1))
edges.append((b, d, 2))
edges.append((c, e, 1))
edges.append((a, b, 1))
edges.append((a, d, 1))
edges.append((c, f, 1))
edges.append((e, f, 3))

# create adjaceny list of neighbors for each node
for edge in edges:
    edge[0].neighbors.append(edge[1])
    edge[0].distances.append(edge[2])
    edge[1].neighbors.append(edge[0])
    edge[1].distances.append(edge[2])

# print the graph
print 'The graph:'
print
for n in graph:
    print 'Node: ', n.label
    print 'Neighbors:'
    for i in range(len(n.neighbors)):
        print n.neighbors[i].label, n.distances[i]
    print

# find the shortest paths to all neighbors starting w/ the given node
startNode = a
print 'Route start node:', startNode.label
startNode.prevNode = startNode
startNode.totalDistance = 0
dijkstra(startNode)

##print
##print 'The graph after Dijkstra:'
##print
##for n in graph:
##    print 'Node:', n.label
##    print 'totalDistance:', n.totalDistance
##    print 'prevNode:', n.prevNode.label
##    print

# print the shortest path to the given node
endNode = f
print 'Route end node:', endNode.label
print 'Route:', route(endNode)
print 'Total distance:', endNode.totalDistance

Diff to Previous Revision

--- revision 4 2010-12-20 23:59:24
+++ revision 5 2011-10-29 18:46:53
@@ -1,6 +1,9 @@
 # Dijkstra Shortest Path Algorithm
 # http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
-# FB - 201012201
+# FB - 201110296
+from heapq import heappush, heappop # for priority queue
+pq = []
+
 class node:
     label = ''
     # adjacency list of the node 
@@ -8,25 +11,33 @@
     distances = [] # distances to neighbors
     # for Dijkstra
     prevNode = None
-    totalDistance = 0
+    totalDistance = float('Inf')
+    visited = False
     # constructor
     def __init__(self, label):
         self.label = label
         self.neighbors = []
         self.distances = []
         self.prevNode = None
-        self.totalDistance = 0
+        self.totalDistance = float('Inf')
+        self.visited = False
+
 
 # find the shortest paths to all nodes recursively
 def dijkstra(node):
     # visit all neighbors and update them if necessary
-    while len(node.neighbors) > 0:
-        n = node.neighbors.pop(0)
-        d = node.distances.pop(0)
-        if n.prevNode == None or n.totalDistance > d + node.totalDistance:
+    for i in range(len(node.neighbors)):
+        n = node.neighbors[i]
+        d = node.distances[i]
+        if n.totalDistance > d + node.totalDistance:
             n.prevNode = node
             n.totalDistance = d + node.totalDistance
-        dijkstra(n)
+            heappush(pq, (n.totalDistance, n))
+    node.visited = True
+
+    (d, ne) = heappop(pq)
+    if not ne.visited:
+        dijkstra(ne)
 
 # get the shortest path to the given node
 def route(endNode):
@@ -53,15 +64,14 @@
 
 # create bidirectional edges of the graph
 edges = []
-edges.append((a, b, 14))
-edges.append((a, c, 9))
-edges.append((a, d, 7))
-edges.append((b, c, 2))
-edges.append((b, f, 9))
-edges.append((c, d, 10))
-edges.append((c, e, 11))
-edges.append((d, e, 15))
-edges.append((f, e, 6))
+edges.append((b, c, 3))
+edges.append((d, e, 1))
+edges.append((b, d, 2))
+edges.append((c, e, 1))
+edges.append((a, b, 1))
+edges.append((a, d, 1))
+edges.append((c, f, 1))
+edges.append((e, f, 3))
 
 # create adjaceny list of neighbors for each node
 for edge in edges:
@@ -84,6 +94,7 @@
 startNode = a
 print 'Route start node:', startNode.label
 startNode.prevNode = startNode
+startNode.totalDistance = 0
 dijkstra(startNode)
 
 ##print

History