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 v ≠ source // 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.