Back

Shortest path algorithm - Dijkstra's pesudo-code and algorithm

Introduction
The code below is an example of an implementation of Dijkstra's algorithm in Python 3. 

The vertices in the graph are given by the following:

Number name
   1          a
   2          b
   3          c
   4          d
   5          e
   6          f

The edges and their weightings are given as follows]

Start   End   Weighting
  a       b          7
  a       c          9
  a       f          14
  b       c         10
  b       d         15
  c       d         11
  c       f          2
  d       e         6
  e       f          9

When you run Dijkstra's algorithm, it should return the shortest path as: a c d e.

The pseudo-code is as follows:

1  function Dijkstra(Graph, source):
 2
 3      dist[source] ← 0                       // Distance from source to source
 4      prev[source] ← undefined               // Previous node in optimal path initialization
 5
 6      for each vertex v in Graph:  // Initialization
 7          if vsource            // Where v has not yet been removed from Q (unvisited nodes)
 8              dist[v] ← infinity             // Unknown distance function from source to v
 9              prev[v] ← undefined            // Previous node in optimal path from source
10          end if 
11          add v to Q                     // All nodes initially in Q (unvisited nodes)
12      end for
13      
14      while Q is not empty:
15          u ← vertex in Q with min dist[u]  // Source node in first case
16          remove u from Q 
17          
18          for each neighbor v of u:           // where v is still in Q.
19              alt ← dist[u] + length(u, v)
20              if alt < dist[v]:               // A shorter path to v has been found
21                  dist[v] ← alt 
22                  prev[v] ← u 
23              end if
24          end for
25      end while
26
27      return dist[], prev[]
28
29  end function

The algorithm is as follows:

from collections import namedtuple
from pprint import pprint as pp
 
 
inf = float('inf')
Edge = namedtuple('Edge', 'start, end, cost')
 
class Graph():
def __init__(self, edges):
self.edges = edges2 = [Edge(*edge) for edge in edges]
self.vertices = set(sum(([e.start, e.end] for e in edges2), []))
 
def dijkstra(self, source, dest):
assert source in self.vertices
dist = {vertex: inf for vertex in self.vertices}
previous = {vertex: None for vertex in self.vertices}
dist[source] = 0
q = self.vertices.copy()
neighbours = {vertex: set() for vertex in self.vertices}
for start, end, cost in self.edges:
neighbours[start].add((end, cost))
#pp(neighbours)
 
while q:
u = min(q, key=lambda vertex: dist[vertex])
q.remove(u)
if dist[u] == inf or u == dest:
break
for v, cost in neighbours[u]:
alt = dist[u] + cost
if alt < dist[v]: # Relax (u,v,a)
dist[v] = alt
previous[v] = u
#pp(previous)
s, u = [], dest
while previous[u]:
s.insert(0, u)
u = previous[u]
s.insert(0, u)
return s
 
 
graph = Graph([("a", "b", 7), ("a", "c", 9), ("a", "f", 14), ("b", "c", 10),
("b", "d", 15), ("c", "d", 11), ("c", "f", 2), ("d", "e", 6),
("e", "f", 9)])
pp(graph.dijkstra("a", "e"))

The above code was taken from Wikipedia via rosettacode.org under the GNU licence and has been tested using Python 3.4 and works. You can copy and paste the above code straight into a Python file, save and then run it for your self. There are working solutions to this problem for another 22 programming languages here.

Back