Last active
August 29, 2015 14:02
-
-
Save hillscottc/7d2e17c59d96e26ec855 to your computer and use it in GitHub Desktop.
Dijkstras Algorithm for shortest path.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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