Skip to content

Commit f34b7d6

Browse files
feat: replace Bellman Ford Algorithm with queue version (#629)
1 parent f4c1677 commit f34b7d6

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

pydatastructs/graphs/algorithms.py

+22-15
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ def shortest_paths(graph: Graph, algorithm: str,
697697
The algorithm to be used. Currently, the following algorithms
698698
are implemented,
699699
700-
'bellman_ford' -> Bellman-Ford algorithm as given in [1].
700+
'bellman_ford' -> Bellman-Ford algorithm as given in [1]
701701
702702
'dijkstra' -> Dijkstra algorithm as given in [2].
703703
source: str
@@ -754,27 +754,34 @@ def shortest_paths(graph: Graph, algorithm: str,
754754
return getattr(algorithms, func)(graph, source, target)
755755

756756
def _bellman_ford_adjacency_list(graph: Graph, source: str, target: str) -> tuple:
757-
distances, predecessor = {}, {}
757+
distances, predecessor, visited, cnts = {}, {}, {}, {}
758758

759759
for v in graph.vertices:
760760
distances[v] = float('inf')
761761
predecessor[v] = None
762+
visited[v] = False
763+
cnts[v] = 0
762764
distances[source] = 0
765+
verticy_num = len(graph.vertices)
763766

764-
edges = graph.edge_weights.values()
765-
for _ in range(len(graph.vertices) - 1):
766-
for edge in edges:
767-
u, v = edge.source.name, edge.target.name
768-
w = edge.value
769-
if distances[u] + edge.value < distances[v]:
770-
distances[v] = distances[u] + w
771-
predecessor[v] = u
767+
que = Queue([source])
772768

773-
for edge in edges:
774-
u, v = edge.source.name, edge.target.name
775-
w = edge.value
776-
if distances[u] + w < distances[v]:
777-
raise ValueError("Graph contains a negative weight cycle.")
769+
while que:
770+
u = que.popleft()
771+
visited[u] = False
772+
neighbors = graph.neighbors(u)
773+
for neighbor in neighbors:
774+
v = neighbor.name
775+
edge_str = u + '_' + v
776+
if distances[u] != float('inf') and distances[u] + graph.edge_weights[edge_str].value < distances[v]:
777+
distances[v] = distances[u] + graph.edge_weights[edge_str].value
778+
predecessor[v] = u
779+
cnts[v] = cnts[u] + 1
780+
if cnts[v] >= verticy_num:
781+
raise ValueError("Graph contains a negative weight cycle.")
782+
if not visited[v]:
783+
que.append(v)
784+
visited[v] = True
778785

779786
if target != "":
780787
return (distances[target], predecessor)

0 commit comments

Comments
 (0)