Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 476aff0

Browse files
Update graph.py
1 parent 2e8ba81 commit 476aff0

File tree

1 file changed

+62
-31
lines changed

1 file changed

+62
-31
lines changed

‎graphs/bellman-ford/graph.py‎

Lines changed: 62 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,75 @@
44
# to all other vertices in weighted graph.
55
# Runtime O(V*E)
66

7+
from typing import Set, Dict, List, Tuple
8+
9+
710
class Graph:
8-
def __init__(self):
9-
self.vertices: list = []
10-
self.edges: list = []
11-
self.distance: dict = {}
12-
self.prev: dict = {}
13-
14-
def add_vertex(self, label: str):
15-
self.vertices.append(label)
16-
self.distance[label] = None
11+
12+
13+
def __init__(self) -> None:
14+
self.vertices:Set[str] = set()
15+
self.edges:List[Tuple[str, str, int]] = list()
16+
self.prev:Dict[str, str] = dict()
17+
self.distances:Dict[str, int] = dict()
18+
19+
20+
def add_vertex(self, label:str) -> None:
21+
self.vertices.add(label)
1722
self.prev[label] = None
23+
self.distances[label] = None
1824

19-
def add_edge(self, label1: str, label2: str, weight: int):
20-
self.edges.append([label1, label2, weight])
2125

22-
def bellman_ford(self, source: str):
23-
self.distance[source] =0
26+
def add_edge(self, v1:str, v2:str, distance:int) ->None:
27+
self.edges.append((v1, v2, distance))
2428

25-
for _ in range(len(self.vertices)):
2629

27-
for edge in self.edges:
28-
label1: str = edge[0]
29-
label2: str = edge[1]
30-
weight: int = edge[2]
30+
def bellman_ford(self, label:str) -> None:
31+
self.distances[label] = 0
3132

32-
if self.distance[label1] is None:
33-
continue
34-
if self.distance[label2] is None:
35-
self.distance[label2] = self.distance[label1] + weight
36-
self.prev[label2] = label1
37-
continue
38-
if self.distance[label1] + weight < self.distance[label2]:
39-
self.distance[label2] = self.distance[label1] + weight
40-
self.prev[label2] = label1
33+
for _ in range(len(self.vertices) - 1):
34+
35+
for v1, v2, distance in self.edges:
36+
if self.distances[v1] is None:
4137
continue
38+
if self.distances[v2] is None or self.distances[v2] > self.distances[v1] + distance:
39+
self.distances[v2] = self.distances[v1] + distance
40+
self.prev[v2] = v1
41+
42+
# Check for negative-weight cycles
43+
for v1, v2, distance in self.edges:
44+
if self.distances[v1] is not None and self.distances[v2] > self.distances[v1] + distance:
45+
raise ValueError("Graph contains a negative-weight cycle")
4246

43-
def print_distances(self, source: str):
47+
self._print_paths(label)
48+
49+
50+
def _print_paths(self, label:str) -> None:
4451
for v in self.vertices:
45-
if v != source:
46-
distance: int = self.distance[v]
47-
print(f'Distance from {source} to {v} is {distance}')
52+
if v == label:
53+
continue
54+
if self.distances[v] is not None:
55+
print(f'Path from {label} to {v} is {self._return_path(v)} and distance is {self.distances[v]}')
56+
else:
57+
print(f'No path from {label} to {v}')
58+
59+
60+
def _return_path(self, label:str) -> str:
61+
if self.prev[label] is None:
62+
return label
63+
return self._return_path(self.prev[label]) + ' -> ' + label
64+
65+
66+
67+
g = Graph()
68+
for v in ['A', 'B', 'C', 'D']:
69+
g.add_vertex(v)
70+
71+
g.add_edge('A', 'B', 1)
72+
g.add_edge('B', 'C', 3)
73+
g.add_edge('A', 'C', 10)
74+
g.add_edge('C', 'D', 2)
75+
g.add_edge('D', 'B', 4)
76+
77+
g.bellman_ford('A')
78+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /