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())
예제 #2
0
    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"))
예제 #3
0
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
예제 #5
0
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)
예제 #7
0
파일: Johnson.py 프로젝트: cloveses/clrs
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)
예제 #9
0
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'
예제 #10
0
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
예제 #11
0
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
예제 #12
0
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'
예제 #13
0
    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)
예제 #15
0
 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])
예제 #16
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)
예제 #18
0
 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)
예제 #19
0
 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)
예제 #20
0
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
예제 #21
0
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
예제 #22
0
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
예제 #23
0
파일: johnsons.py 프로젝트: boky90/learning
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)]
예제 #24
0
파일: johnsons.py 프로젝트: creasyw/Courses
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
예제 #26
0
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
예제 #29
0
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
예제 #31
0
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)
예제 #32
0
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'])
예제 #33
0
        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)
예제 #34
0
        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)
예제 #35
0
    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)