def pairs_of_shortest_paths(graph, weight_attribute='weight', infinity=65536): ''' Computes all pairs of shortest paths in graph. Infinity should be specified, otherwise 65536 will be chosen. Returns dict with shortest paths, where dict[u][v] is the length of the shortest path between u and v, or infinity if there is no path between them. ''' distance = {} for node in graph: distance[node] = defaultdict(lambda: infinity) distance[node][node] = 0 for u, v, data in edge_iter(graph): distance[u][v] = data[weight_attribute] for u in graph: for v in graph: for w in graph: if distance[v][u] + distance[u][w] < distance[v][w]: distance[v][w] = distance[v][u] + distance[u][w] return dict(distance)
def shortest_paths_from(graph, start, weight_attribute='weight'): ''' Returns (predecessors, distance). predecessors[node] is the predecessor of node in the shortest path, distance[node] is the shortest-path's lenght to node. No negative cycles allowed! ''' if start not in graph: raise NodeNotFound( "Node {0} is not in the graph!".format(start)) distance = {start: 0} predecessors = {start: None} for i in range(0, graph.order()): for u, distance_u in list(distance.items()): for v, data in graph[u].items(): if (v not in distance or distance[v] > distance_u + data[weight_attribute]): distance[v] = distance_u + data[weight_attribute] predecessors[v] = u for (u, v, attributes) in edge_iter(graph): if u in distance and v in distance: if distance[v] > distance[u] + attributes[weight_attribute]: raise NegativeCycle("Negative cycle found!") return (predecessors, distance)