Skip to content

Instantly share code, notes, and snippets.

@hillscottc
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hillscottc/7d2e17c59d96e26ec855 to your computer and use it in GitHub Desktop.
Save hillscottc/7d2e17c59d96e26ec855 to your computer and use it in GitHub Desktop.
Dijkstras Algorithm for shortest path.
"""
Dijkstra's algorithm for shortest paths.
http://code.activestate.com/recipes/577343-dijkstras-algorithm-for-shortest-paths/)
- dijkstra(G, s) finds all shortest paths from s to each other vertex.
- shortest_path(G, s, t) uses dijkstra to find the shortest path from s to t.
The input graph G is assumed to have the following representation:
- A vertex can be any object that can be used as an index into a dictionary.
- G is a dictionary, indexed by vertices.
- For any vertex v, G[v] is itself a dictionary, indexed by neighbors of v.
- For any edge v->w, G[v][w] is the length of the edge.
"""
from priodict import priorityDictionary
def dijkstra(graph, start, end=None):
final_distances = {}
predecessors = {}
estimated_distances = priorityDictionary()
estimated_distances[start] = 0
for vertex in estimated_distances:
final_distances[vertex] = estimated_distances[vertex]
if vertex == end:
break
for edge in graph[vertex]:
path_distance = final_distances[vertex] + graph[vertex][edge]
if edge in final_distances:
if path_distance < final_distances[edge]:
raise ValueError("Better path to already-final vertex")
elif edge not in estimated_distances or path_distance < estimated_distances[edge]:
estimated_distances[edge] = path_distance
predecessors[edge] = vertex
return final_distances, predecessors
def shortest_path(graph, start, end):
"""
Find a single shortest path from the given start vertex to the given end,
output as list of vertices in order along the shortest path.
"""
final_distances, predecessors = dijkstra(graph, start, end)
path = []
while 1:
path.append(end)
if end == start:
break
end = predecessors[end]
path.reverse()
return path
if __name__ == "____main__":
pass
# G = {'s':{'u':10, 'x':5}, 'u':{'v':1, 'x':2}, 'v':{'y':4},
# 'x':{'u':3, 'v':9, 'y':2}, 'y':{'s':7, 'v':6}}
# The shortest path from s to v is ['s', 'x', 'u', 'v'] and has length 9.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment