def test(): print 'Testando grafo de exemplo do livro Algoritmos 3rd (Cormen), página 480.' g = grafo(direcionado=True) g.inserir_vertice('a') g.inserir_vertice('b') g.inserir_vertice('c') g.inserir_vertice('d') g.inserir_vertice('e') g.inserir_aresta('a', 'b', 6) g.inserir_aresta('a', 'c', 7) g.inserir_aresta('a', 'e', 2) g.inserir_aresta('b', 'd', 5) g.inserir_aresta('b', 'c', 8) g.inserir_aresta('b', 'e', -4) g.inserir_aresta('c', 'd', -3) g.inserir_aresta('c', 'e', 9) g.inserir_aresta('d', 'b', -2) g.inserir_aresta('e', 'd', 7) bellman_ford(g, 'd') for v in g.get_vertices(): caminho = [v.get_id()] caminho_minino(v, caminho) print 'O menor caminho é: %s com custo %d.' % (caminho[::-1], v.get_distancia())
def test_bellman_ford_int_vertices_negaitve(self): graph = Graph() graph.add_edge(Edge(Vertex(1), Vertex(2), 1)) graph.add_edge(Edge(Vertex(1), Vertex(4), 1)) graph.add_edge(Edge(Vertex(3), Vertex(4), 1)) graph.add_edge(Edge(Vertex(4), Vertex(2), 1)) self.assertEqual(bellman_ford(graph, Vertex(5), Vertex(0)), float("inf")) self.assertEqual(bellman_ford(graph, Vertex(1), Vertex(5)), float("inf"))
def johnson(G): duv = [[0 for i in range(len(G))]for j in range(len(G))] _G = copy.copy(G) x = len(G) tmp = {} for i in G.keys(): tmp.update({i:0}) _G.update({x:tmp}) d = bellman_ford(_G,x) if d == False: print "the input graph contains a negative-weight cycle" return else: h = {} for i in _G.keys(): h.update({i:d[i]}) #print 'h:',h for u in _G.keys(): for v in _G[u]: _G[u][v] = _G[u][v] + h[u] - h[v] #print _G for u in G.keys(): d = dijkstra(_G,u) #print u,d for v in G.keys(): duv[u][v] = d[v] + h[v] - h[u] return duv
def johnson(G, w): # 计算G' # 对G加入一源节点s # 使得(s, v) = 0 G1, s, w = compute_G(G, w) if False == bellman_ford(G1, w, s): raise "graph contain negative-weight cycle" else: # 计算h(v) h = {} for v in G1.V: h[v] = v.d # 更新w w1 = {} for u in G1.V: for v in G1.E[u]: w1[(u, v)] = w[u, v] + h[u] - h[v] n = len(G.V) D = [[0 for j in range(n)] for i in range(n)] # 使用Dijkstra算法 for u in G.V: dijkstra(G, w1, u) for v in G.V: D[u.value - 1][v.value - 1] = v.d + h[v] - h[u] return D
def johnson(graph): nodes = graph.nodes.keys() edges = graph.edges new_edges = [] for node in nodes: new_edges.append((0, node, 0)) new_edges += edges nodes += [0] nodes.sort() graph_temp = DiGraph() graph_temp.add_nodes(nodes) graph_temp.add_edges(new_edges) dist = bellman_ford(graph_temp, 0) dist.pop() new_edges = [] nodes.remove(0) for edge in edges: u, v, wt = edge new_edges.append((u, v, wt + dist[u - 1] - dist[v - 1])) print new_edges graph_temp = DiGraph() graph_temp.add_nodes(nodes) graph_temp.add_edges(new_edges()) for node in nodes: pass
def test_negativecycle(self): # Because of negative cycles, we shall denote the shortest path for these # as -infinity. G = { 1: { 2: 5, 3: 20 }, 2: { 4: 10 }, 3: { 5: 10 }, 4: {}, 5: { 6: 5 }, 6: { 3: -20 } } correct_shortest_dist = { 1: 0, 2: 5, 3: -float('inf'), 4: 15, 5: -float('inf'), 6: -float('inf') } shortest_dist, _ = bellman_ford(G, 1) self.assertEqual(shortest_dist, correct_shortest_dist)
def johnson(g, w): vertexes_g = g.get_v() edges_g = g.get_e() s = NameVertex('s') vertexes_g1 = [s] + vertexes_g edges_g1 = edges_g.copy() for vertex in vertexes_g: edges_g1.append(Edge(s, vertex, 0)) graph2 = DirectedGraph(vertexes_g1, edges_g1) if bellman_ford(graph2, w, s) == False: print("the in put graph contains a negative_weight cycle") else: h = dict() for vertex in vertexes_g1: h[vertex] = vertex.d def weight1(edge): return w(edge) + h[edge.u] - h[edge.v] n = len(vertexes_g) d = dict() for u in vertexes_g: dijkstra(g, weight1, u) d[u] = dict() for v in vertexes_g: d[u][v] = v.d + h[v] - h[u] return d
def test_emptygraph(self): G = {} start_node = 1 # Cant run an empty graph without returning error with self.assertRaises(ValueError): shortest_dist, _ = bellman_ford(G, start_node)
def test(): print 'Testando um grafo com ciclo negativo' g = grafo(direcionado=True) g.inserir_vertice('a') g.inserir_vertice('b') g.inserir_vertice('c') g.inserir_vertice('d') g.inserir_vertice('e') g.inserir_vertice('f') g.inserir_aresta('b', 'a', -3) g.inserir_aresta('a', 'c', 5) g.inserir_aresta('c', 'b', 2) g.inserir_aresta('d', 'b', 4) g.inserir_aresta('d', 'c', 5) g.inserir_aresta('c', 'f', -3) g.inserir_aresta('e', 'c', 4) g.inserir_aresta('e', 'f', 5) g.inserir_aresta('f', 'd', -4) if bellman_ford(g, 'a'): for v in g.get_vertices(): caminho = [v.get_id()] caminho_minino(v, caminho) print 'O menor caminho é: %s com custo %d.' % (caminho[::-1], v.get_distancia()) else: print 'Ciclo negativo encontrado'
def johnson(graph: Graph, type: str = 'copy'): def transform_vertices(graph_matrix: list, distance: list): for i in range(len(graph_matrix)): for j in range(len(graph_matrix[i])): graph_matrix[i][j] += distance[i] - distance[j] def rollback_vertices(graph_matrix: list, distance: list): for i in range(len(graph_matrix)): for j in range(len(graph_matrix[i])): graph_matrix[i][j] += -distance[i] + distance[j] total_v = graph.get_total_v() new_graph = add_vertice(graph,[0]*(total_v + 1)) new_total_v = new_graph.get_total_v() distance_bf = bellman_ford(new_graph, new_total_v - 1) graph_matrix = graph.get_matrix(type) transform_vertices(graph_matrix, distance_bf) result = [] for i in range(len(graph_matrix)): result.append(dijkstra(Graph(graph_matrix), i)) rollback_vertices(result, distance_bf) return result
def johnson(graph): """ All pair shortest path algorithm with complexity O(nmlogn) for graph with negative edges - Create a new graph with a grounded node which has oneway connections to all other nodes - First use bellman_ford to reweight c_uv' = c_uv + p(v) - p(u) AND to detect negative cost cycles if present - Then apply Dijkstra on the reweighted graph to find shortest path - Then transformed shortest path values back to the unweighted values c_uv = c_uv' + p(u) - p(v) """ V = list(set([k for v in graph.values() for k in v] + graph.keys())) grounded_graph = deepcopy(graph) grounded_graph['ground'] = {v: 0 for v in V} weights = bellman_ford(grounded_graph, 'ground') if not weights: # ncc detected return None reweighted_graph = { u: {v: c + weights[u] - weights[v] for v, c in d.iteritems()} for u, d in graph.iteritems() } # dijkstra n times apsp = {v: dijkstra(reweighted_graph, v) for v in V} # unweight apsp = { u: {v: c - weights[u] + weights[v] for v, c in d.iteritems()} for u, d in apsp.iteritems() } return apsp
def test(): #disponivel http://www.fernandolobo.info/aed-II/teoricas/a24e25.print.pdf print 'Testando grafo de exemplo das aulas do prof. Fernando Lobo da universidade Algarve in Portugal.' g = grafo(direcionado=True) g.inserir_vertice('a') g.inserir_vertice('b') g.inserir_vertice('c') g.inserir_vertice('d') g.inserir_vertice('e') g.inserir_aresta('a', 'b', 10) g.inserir_aresta('a', 'c', 3) g.inserir_aresta('b', 'c', 1) g.inserir_aresta('b', 'd', 2) g.inserir_aresta('c', 'b', 4) g.inserir_aresta('c', 'd', 8) g.inserir_aresta('c', 'e', 2) g.inserir_aresta('d', 'e', 7) g.inserir_aresta('e', 'd', 9) if bellman_ford(g, 'a'): for v in g.get_vertices(): caminho = [v.get_id()] caminho_minino(v, caminho) print 'O menor caminho é: %s com custo %d.' % (caminho[::-1], v.get_distancia()) else: print 'Ciclo negativo encontrado'
def test_bellman_ford_str_vertices_negative(self): graph = Graph() graph.add_edge(Edge(Vertex("A"), Vertex("D"), 2)) graph.add_edge(Edge(Vertex("A"), Vertex("G"), 3)) graph.add_edge(Edge(Vertex("A"), Vertex("B"), 1)) graph.add_edge(Edge(Vertex("B"), Vertex("E"), 6)) graph.add_edge(Edge(Vertex("B"), Vertex("F"), 7)) graph.add_edge(Edge(Vertex("F"), Vertex("D"), 10)) graph.add_edge(Edge(Vertex("F"), Vertex("C"), 12)) graph.add_edge(Edge(Vertex("E"), Vertex("G"), 9)) self.assertEqual(bellman_ford(graph, Vertex("A"), Vertex("C")), 20) self.assertEqual(bellman_ford(graph, Vertex("A"), Vertex("F")), 8) self.assertEqual(bellman_ford(graph, Vertex("B"), Vertex("G")), 15) self.assertEqual(bellman_ford(graph, Vertex("E"), Vertex("A")), float("inf")) self.assertEqual(bellman_ford(graph, Vertex("C"), Vertex("D")), float("inf"))
def testWeighted(self): for i in range(50): adjList = self.randG.randomGnmGraph(n=50, M=1000, isWeighted=True) nodes, edges = self.randG.toNodeEdges(adjList) src = random.choice(list(adjList.keys())) dist1, prev1 = dijkstra(adjList, src) dist2, prev2 = bellman_ford(nodes, edges, src) dist3, prev3 = shortest_path_faster(adjList, src) self.assertEqual(dist1, dist2) self.assertEqual(dist2, dist3)
def testrandomCompare(self): # TODO: We need to make sure this test is run in the same dir # as adj_local.json and dummy.json with open('adj_local.json') as data_file: graph = json.load(data_file) for i in range(0, 10): src = list(graph.keys())[randint(0, len(graph.keys()) - 1)] print("Checking source node " + src) d_results = dijkstra(graph, src) bf_results = bf.bellman_ford(graph, src)[0] for node, dist in bf_results.items(): self.assertEqual(dist, d_results[node][0])
def test_bellman_ford_int_vertices_positive(self): graph = Graph() graph.add_edge(Edge(Vertex(0), Vertex(1), 1)) graph.add_edge(Edge(Vertex(0), Vertex(4), 1)) graph.add_edge(Edge(Vertex(1), Vertex(0), 1)) graph.add_edge(Edge(Vertex(1), Vertex(3), 1)) graph.add_edge(Edge(Vertex(1), Vertex(4), 1)) graph.add_edge(Edge(Vertex(1), Vertex(2), 1)) graph.add_edge(Edge(Vertex(2), Vertex(3), 1)) graph.add_edge(Edge(Vertex(2), Vertex(1), 1)) graph.add_edge(Edge(Vertex(3), Vertex(1), 1)) graph.add_edge(Edge(Vertex(3), Vertex(2), 1)) graph.add_edge(Edge(Vertex(3), Vertex(4), 1)) self.assertEqual(bellman_ford(graph, Vertex(0), Vertex(2)), 2) self.assertEqual(bellman_ford(graph, Vertex(1), Vertex(2)), 1) self.assertEqual(bellman_ford(graph, Vertex(2), Vertex(2)), 0) self.assertEqual(bellman_ford(graph, Vertex(3), Vertex(2)), 1) self.assertEqual(bellman_ford(graph, Vertex(2), Vertex(4)), 2)
def test_shortestdist(self): G = {1: {2: 100, 3: 5}, 2: {4: 20}, 3: {2: 10}, 4: {}} start_node = 1 shortest_dist, _ = bellman_ford(G, start_node) # Test distance to starting node should be 0 self.assertEqual(shortest_dist[start_node], 0) # Test shortest distances from graph self.assertEqual(shortest_dist[2], 15) self.assertEqual(shortest_dist[3], 5) self.assertEqual(shortest_dist[4], 35)
def test_bellman_ford_1(self): graph = [ #s, 1, 2, 3, 4, t [0, 6, 8, 18, 0, 0], #s [6, 0, 0, 0, 11, 0], #1 [8, 0, 0, 9, 0, 7], #2 [18, 0, 9, 0, 0, 4], #3 [0, 11, 0, 0, 0, 3], #4 [0, 0, 7, 4, 3, 0], #t ] exp = [0, 2, 5] start = 0 goal = 5 self.assertEqual(bellman_ford.bellman_ford(graph, start, goal), exp)
def test_bellman_ford_2(self): graph = [ #s, 1, 2, 3, 4, t [0, 5, 4, 2, 0, 0], #s [5, 0, 2, 0, 0, 6], #1 [4, 2, 0, 3, 2, 0], #2 [2, 0, 3, 0, 6, 0], #3 [0, 0, 2, 6, 0, 4], #4 [0, 6, 0, 0, 4, 0], #t ] exp = [0, 2, 4, 5] start = 0 goal = 5 self.assertEqual(bellman_ford.bellman_ford(graph, start, goal), exp)
def johnsons(file): """ Implementation of Johnsons all pairs shortest paths algorithm Returns: list of list of all path lengths to each node, where index refers to vertex """ graph, n, m = load_graph(file) # prep graph for bellman ford graph[0] = [] for i in range(1, n + 1): graph[0].append((i, 0)) # determine vertex weights print("Running Bellman-Ford...") weights = bellman_ford(graph, n, 0) if weights == "Negative cycle detected": return False # create re-weighted graph print("Creating re-weighted graph...") del graph[0] graph_reweighted = {} for u in range(1, n + 1): if graph_reweighted.get(u) == None: graph_reweighted[u] = [] for v, w in graph[u]: graph_reweighted[u].append((v, w + weights[u] - weights[v])) # run Djikstra using every vertex as a source print("Running Djikstra...") all_shortest_paths = [[float("Inf")]] * (n + 1) for source in range(1, n + 1): if source % 50 == 0: print("on vertex # " + str(source)) all_shortest_paths[source] = djikstra(graph_reweighted, n, source) # re-adjust results to show true lengths print("Adjusting lengths...") for u in range(1, n + 1): for v in range(1, n + 1): if all_shortest_paths[u][v] != float("Inf"): all_shortest_paths[u][v] += weights[v] - weights[u] return all_shortest_paths
def _compute_potentials(graph): assert isinstance(graph, Graph) # add new source with arcs to all vertices graph, new_source = graph_helper.add_new_source(graph, range(len(graph)), 0) # now distance can be 0 or less than 0 marks, _, last_relaxed_vertices = bellman_ford(graph, new_source) marks = marks[:new_source] + marks[new_source + 1:] # exclude distance to added source potentials = [-x for x in marks] # potential is a negative distance has_negative_cycle = bool(last_relaxed_vertices) return potentials, has_negative_cycle
def _find_shortest_path(portfolio, target_currency, transformed_rates): source_currency = None final_predecessor = None shortest_distance = float('Inf') for name, amount in portfolio.currencies.items(): if name == target_currency: continue distance, predecessor = bellman_ford(transformed_rates, name) if distance[target_currency] < shortest_distance: shortest_distance = distance[target_currency] final_predecessor = predecessor source_currency = name if source_currency is None: raise RuntimeError('No route to {}'.format(target_currency)) route = _build_route(final_predecessor, source_currency, target_currency) return source_currency, route
def johonsons(data, vertex): d1 = data.copy() # make psedu node pointing to all other nodes with zero cost plus1 = vertex + 1 d1[plus1] = {} for i in range(1, plus1): d1[plus1][i] = 0 # calculate the reweight vector reweight = bellman_ford(d1, plus1, plus1) # reweight all cost to make it nonnegative if type(reweight) == float: # stop if there is any negative cycle in the graph return None else: for i in data: for k in data[i]: data[i][k] = data[i][k] + reweight[i] - reweight[k] result = [] return [min(reconvert(reweight,vertex,dijkstras(data,i),i))\ for i in range(1,vertex+1)]
def johnson(nodes, edges): sentinel = -1 for node in nodes: edges.append((sentinel, node, 0)) nodes.append(sentinel) weights, prev = bellman_ford(nodes, edges, sentinel) if weights is None: return None, "Negative Cycle" nodes.pop() del edges[-len(nodes):] adjList = {node: [] for node in nodes} for u, v, w in edges: adjList[u].append((v, w + weights[u] - weights[v])) dist, prev = {}, {} for src in nodes: dist[src], prev[src] = dijkstra(adjList, src) for dest in dist[src]: dist[src][dest] -= (weights[src] - weights[dest]) return dist, prev
def johnson( graph: _adj_list_t, new_vert_name: t.Any = -1 ) -> t.Tuple[np.ndarray, t.Dict[t.Any, int]]: if new_vert_name in graph: raise ValueError( f"'new_vert_name' ({new_vert_name}) in graph. Please use another value." ) # Add a new supersource vertex and run Bellman-Ford algorithm graph[new_vert_name] = [(v, 0) for v in graph.keys()] bf_res, bf_success = bellman_ford.bellman_ford(graph, source=new_vert_name) graph.pop(new_vert_name) # Check for negative weight cycles if not bf_success: raise ValueError("Graph has a negative weight cycle.") # Adjust weights to be all non-negative using Bellman-Ford results for v, e in graph.items(): for ind, (v_adj, w) in enumerate(e): graph[v][ind] = v_adj, w + bf_res[v][1] - bf_res[v_adj][1] num_vert = len(graph.keys()) D = np.zeros((num_vert, num_vert)) vert_inds = {v: i for i, v in enumerate(graph.keys())} # Run Dijkstra's algorithm for every node as the source for v, e in graph.items(): dj_res = dijkstra.dijkstra(graph, source=v) cur_v_ind = vert_inds[v] for v_tg, (_, w) in dj_res.items(): tg_ind = vert_inds[v_tg] D[cur_v_ind, tg_ind] = w + bf_res[v_tg][1] - bf_res[v][1] # Set graph weights back to original value for v, e in graph.items(): for ind, (v_adj, w) in enumerate(e): graph[v][ind] = v_adj, w - bf_res[v][1] + bf_res[v_adj][1] return D, vert_inds
def find_negative_weight_cycle(graph): suspect_edge = set() cycle = set() for i in range(graph.v_num): shortest, pred = bellman_ford(graph, i) for m in range(graph.v_num): for k in range(graph.v_num): if shortest[m]+graph.adjacency_matrix[m, k]<shortest[k]: suspect_edge.add((m, k)) for (u, v) in suspect_edge: visited = [False] * graph.v_num x = v while visited[x] is False: visited[x] = True x = pred[x] v = pred[x] sub_cycle = [x] while v != x: sub_cycle = [v] + sub_cycle v = pred[v] cycle.add(tuple(sub_cycle)) return cycle
def trans_dc_to_graph_and_calc(dc): vertexes = [] temp_locals = locals() for i in range(dc.n + 1): vetex_name = 'v' + str(i) temp_locals[vetex_name] = NameVertex(vetex_name) vertexes.append(eval(vetex_name)) edges = [] for num in range(dc.m): i = a[num].index(-1) + 1 j = a[num].index(1) + 1 edge = Edge(eval('v' + str(i)), eval('v' + str(j)), b[num]) edges.append(edge) for num in range(1, dc.n + 1): edge = Edge(eval('v0'), eval('v' + str(num)), 0) edges.append(edge) graph1 = DirectedGraph(vertexes, edges) bf_result = bellman_ford(graph1, weight, eval('v0')) result = None if bf_result: result = [] for i in range(1, dc1.n + 1): result.append(getattr(eval('v' + str(i)), 'd')) return result
def solve(A: np.ndarray, b: np.ndarray, check_A: bool = True) -> np.ndarray: """Solve a system of difference constraints Ax <= b. The A matrix must have a single '1' and a single '-1' in each row. All other entries must be 0. """ if b.ndim > 1: b = b.ravel() if A.shape[0] != b.size: raise ValueError("Number of rows in A must match the size of b.") if A.shape[1] > A.shape[0]: raise ValueError( "Number of constraints can't be smaller than number of variables.") graph = {i: [] for i in np.arange(A.shape[1])} for const, upper_b in zip(A, b): ind_pos = np.flatnonzero(const == +1)[0] ind_neg = np.flatnonzero(const == -1)[0] graph[ind_neg].append((ind_pos, upper_b)) graph[-1] = [(i, 0) for i in np.arange(A.shape[1])] sol, success = bellman_ford.bellman_ford(graph, source=-1) if not success: raise ValueError( "Negative weight cycle found: system has no solution.") # Remove the artificial node from the bellman-ford results sol.pop(-1) # Solution is the smallest distance from each node to the artificial node return np.fromiter((d for _, d in sol.values()), dtype=float)
def find_negative_weight_cycle(graph): suspect_edge = set() cycle = set() for i in range(graph.v_num): shortest, pred = bellman_ford(graph, i) for m in range(graph.v_num): for k in range(graph.v_num): if shortest[m] + graph.adjacency_matrix[m, k] < shortest[k]: suspect_edge.add((m, k)) for (u, v) in suspect_edge: visited = [False] * graph.v_num x = v while visited[x] is False: visited[x] = True x = pred[x] v = pred[x] sub_cycle = [x] while v != x: sub_cycle = [v] + sub_cycle v = pred[v] cycle.add(tuple(sub_cycle)) return cycle
with open(args.graphFile) as data_file: try: adj_list = json.load(data_file) except: print("ERROR: -graph argument must point to a valid JSON file") sys.exit(1) if args.source not in adj_list.keys(): print("ERROR: -source argument must be a Vertex in the graph provided") sys.exit(1) def printResults(algo, src, results, runtime): print(algo + " Shortest Path Results from vertex " + str(src) + ":") pprint(results) print(algo + " ran in " + str(runtime * 1000.0) + " ms") if (args.algo == 'both') or (args.algo == 'dijkstra'): start = time.time() shortPaths = dijkstra(adj_list, args.source) end = time.time() runtime = end - start printResults('Dijkstra', args.source, shortPaths, runtime) if (args.algo == 'both') or (args.algo == 'bellmanford'): start = time.time() shortPaths = bf.bellman_ford(adj_list, args.source)[0] end = time.time() runtime = end - start printResults('Bellman-Ford', args.source, shortPaths, runtime)
import weighted_graph import bellman_ford node_numbers = {'N1':0, 'N2':1, 'N3':2, 'N4':3, 'N5':4, 'N6':5, 'N7':6, 'N8':7} G = weighted_graph.Graph(len(node_numbers)) for node in node_numbers: G.set_vertex(node_numbers[node],node) G.add_edge(node_numbers['N1'],node_numbers['N2'],3) G.add_edge(node_numbers['N1'],node_numbers['N4'],2) G.add_edge(node_numbers['N1'],node_numbers['N3'],3) G.add_edge(node_numbers['N2'],node_numbers['N4'],9) G.add_edge(node_numbers['N2'],node_numbers['N5'],4) G.add_edge(node_numbers['N2'],node_numbers['N7'],2) G.add_edge(node_numbers['N3'],node_numbers['N4'],4) G.add_edge(node_numbers['N3'],node_numbers['N5'],1) G.add_edge(node_numbers['N3'],node_numbers['N7'],6) G.add_edge(node_numbers['N3'],node_numbers['N8'],-6) G.add_edge(node_numbers['N4'],node_numbers['N6'],1) G.add_edge(node_numbers['N5'],node_numbers['N7'],7) G.print_graph() bellman_ford.bellman_ford(G,node_numbers['N1'])
path.append(end) if path.count(end) > 1: path = path[path.index(end):] path.reverse() path = path[path.index(end):] return path end = predecessor[end] symbols = set() graph = defaultdict(dict) for line in sys.stdin: src,dst,weight = (s.strip() for s in line.split(',')) symbols.add(src) symbols.add(dst) rate = float(weight) if rate != 0.0: graph[src][dst] = log(1/rate) for src in symbols: distances,predecessors,cycle_vertex = bellman_ford(graph,src) if cycle_vertex is not None: print cycle_vertex print negative_weight_cycle(predecessors,cycle_vertex) sys.exit() else: print " does not have a negative weight cycle" for dst in distances: if src == dst or distances[dst] == float('inf'): continue print find_path(predecessors,src,dst)
if path.count(end) > 1: path = path[path.index(end):] path.reverse() path = path[path.index(end):] return path end = predecessor[end] symbols = set() graph = defaultdict(dict) for line in sys.stdin: src, dst, weight = (s.strip() for s in line.split(',')) symbols.add(src) symbols.add(dst) rate = float(weight) if rate != 0.0: graph[src][dst] = log(1 / rate) for src in symbols: distances, predecessors, cycle_vertex = bellman_ford(graph, src) if cycle_vertex is not None: print cycle_vertex print negative_weight_cycle(predecessors, cycle_vertex) sys.exit() else: print " does not have a negative weight cycle" for dst in distances: if src == dst or distances[dst] == float('inf'): continue print find_path(predecessors, src, dst)
def testKnownData(self): with open('dummy.json') as data_file: graph = json.load(data_file) a_paths = { 'a': 0, 'b': 2, 'c': 1, 'd': 5, 'e': 5, 'f': 4, 'g': 4, 'h': 4, 'i': 4, 'j': 5, 'k': 4, 'l': 4, 'm': 5, 'n': 4, 'o': 4, 'p': 5, 'q': 5, 'r': 5, 's': 5, 't': 3, 'u': 5, 'v': 4, 'w': 3, 'x': 4, 'y': 4, 'z': 3, } shortest = dijkstra(graph, 'a') for node, dist in a_paths.items(): self.assertEqual(shortest[node][0], dist) shortest = bf.bellman_ford(graph, 'a')[0] for node, dist in a_paths.items(): self.assertEqual(shortest[node], dist) m_paths = { 'a': 5, 'b': 3, 'c': 4, 'd': 3, 'e': 3, 'f': 3, 'g': 2, 'h': 3, 'i': 2, 'j': 1, 'k': 3, 'l': 3, 'm': 0, 'n': 2, 'o': 2, 'p': 3, 'q': 1, 'r': 1, 's': 2, 't': 3, 'u': 3, 'v': 2, 'w': 3, 'x': 1, 'y': 3, 'z': 2, } shortest = dijkstra(graph, 'm') for node, dist in m_paths.items(): self.assertEqual(shortest[node][0], dist) shortest = bf.bellman_ford(graph, 'm')[0] for node, dist in m_paths.items(): self.assertEqual(shortest[node], dist)