Skip to content

Commit 4b54674

Browse files
authored
change ford_fulkerson.py
1 parent a71618f commit 4b54674

File tree

1 file changed

+47
-32
lines changed

1 file changed

+47
-32
lines changed

networking_flow/ford_fulkerson.py

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
(2) Choose the augmenting path from source to sink and add the path to flow
88
"""
99

10+
from collections import deque
11+
from typing import List
12+
1013
graph = [
1114
[0, 16, 13, 0, 0, 0],
1215
[0, 0, 10, 12, 0, 0],
@@ -17,7 +20,7 @@
1720
]
1821

1922

20-
def breadth_first_search(graph: list, source: int, sink: int, parents: list) -> bool:
23+
def breadth_first_search(graph: List[List[int]], source: int, sink: int, parents: List[int]) -> bool:
2124
"""
2225
This function returns True if there is a node that has not iterated.
2326
@@ -37,25 +40,31 @@ def breadth_first_search(graph: list, source: int, sink: int, parents: list) ->
3740
...
3841
IndexError: list index out of range
3942
"""
40-
visited = [False] * len(graph) # Mark all nodes as not visited
41-
queue = [] # breadth-first search queue
42-
43-
# Source node
43+
num_nodes = len(graph)
44+
visited = [False] * num_nodes
45+
queue = deque()
46+
4447
queue.append(source)
4548
visited[source] = True
46-
49+
4750
while queue:
48-
u = queue.pop(0) # Pop the front node
49-
# Traverse all adjacent nodes of u
50-
for ind, node in enumerate(graph[u]):
51-
if visited[ind] is False and node > 0:
52-
queue.append(ind)
53-
visited[ind] = True
54-
parents[ind] = u
51+
current_node = queue.popleft()
52+
53+
# If we reached the sink, we can stop early
54+
if current_node == sink:
55+
return True
56+
57+
# Check all adjacent nodes
58+
for neighbor, capacity in enumerate(graph[current_node]):
59+
if not visited[neighbor] and capacity > 0:
60+
visited[neighbor] = True
61+
parents[neighbor] = current_node
62+
queue.append(neighbor)
63+
5564
return visited[sink]
5665

5766

58-
def ford_fulkerson(graph: list, source: int, sink: int) -> int:
67+
def ford_fulkerson(graph: List[List[int]], source: int, sink: int) -> int:
5968
"""
6069
This function returns the maximum flow from source to sink in the given graph.
6170
@@ -80,28 +89,34 @@ def ford_fulkerson(graph: list, source: int, sink: int) -> int:
8089
>>> ford_fulkerson(test_graph, 0, 5)
8190
23
8291
"""
83-
# This array is filled by breadth-first search and to store path
84-
parent = [-1] * (len(graph))
92+
# Create a copy of the graph to avoid modifying the original
93+
residual_graph = [row[:] for row in graph]
94+
num_nodes = len(residual_graph)
95+
parents = [-1] * num_nodes
8596
max_flow = 0
8697

87-
# While there is a path from source to sink
88-
while breadth_first_search(graph, source, sink, parent):
89-
path_flow = int(1e9) # Infinite value
90-
s = sink
91-
92-
while s != source:
93-
# Find the minimum value in the selected path
94-
path_flow = min(path_flow, graph[parent[s]][s])
95-
s = parent[s]
96-
98+
# Augment the flow while there is a path from source to sink
99+
while breadth_first_search(residual_graph, source, sink, parents):
100+
# Find the minimum residual capacity along the path
101+
path_flow = float('inf')
102+
current_node = sink
103+
104+
# Find the minimum capacity in the path
105+
while current_node != source:
106+
parent_node = parents[current_node]
107+
path_flow = min(path_flow, residual_graph[parent_node][current_node])
108+
current_node = parent_node
109+
110+
# Add path flow to overall flow
97111
max_flow += path_flow
98-
v = sink
99112

100-
while v != source:
101-
u = parent[v]
102-
graph[u][v] -= path_flow
103-
graph[v][u] += path_flow
104-
v = parent[v]
113+
# Update residual capacities of the edges and reverse edges
114+
current_node = sink
115+
while current_node != source:
116+
parent_node = parents[current_node]
117+
residual_graph[parent_node][current_node] -= path_flow
118+
residual_graph[current_node][parent_node] += path_flow
119+
current_node = parent_node
105120

106121
return max_flow
107122

0 commit comments

Comments
 (0)