Skip to content

Add function docstrings, comments and type hints #10893

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 24, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 80 additions & 29 deletions networking_flow/ford_fulkerson.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,95 @@
# Ford-Fulkerson Algorithm for Maximum Flow Problem
"""
Ford-Fulkerson Algorithm for Maximum Flow Problem
* https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm

Description:
(1) Start with initial flow as 0;
(2) Choose augmenting path from source to sink and add path to flow;
(1) Start with initial flow as 0
(2) Choose the augmenting path from source to sink and add the path to flow
"""
graph = [
[0, 16, 13, 0, 0, 0],
[0, 0, 10, 12, 0, 0],
[0, 4, 0, 0, 14, 0],
[0, 0, 9, 0, 0, 20],
[0, 0, 0, 7, 0, 4],
[0, 0, 0, 0, 0, 0],
]


def breadth_first_search(graph: list, source: int, sink: int, parents: list) -> bool:
"""
This function returns True if there is a node that has not iterated.

Args:
graph: Adjacency matrix of graph
source: Source
sink: Sink
parents: Parent list

Returns:
True if there is a node that has not iterated.

>>> breadth_first_search(graph, 0, 5, [-1, -1, -1, -1, -1, -1])
True
>>> breadth_first_search(graph, 0, 6, [-1, -1, -1, -1, -1, -1])
Traceback (most recent call last):
...
IndexError: list index out of range
"""
visited = [False] * len(graph) # Mark all nodes as not visited
queue = [] # breadth-first search queue

def bfs(graph, s, t, parent):
# Return True if there is node that has not iterated.
visited = [False] * len(graph)
queue = []
queue.append(s)
visited[s] = True
# Source node
queue.append(source)
visited[source] = True

while queue:
u = queue.pop(0)
for ind in range(len(graph[u])):
if visited[ind] is False and graph[u][ind] > 0:
u = queue.pop(0) # Pop the front node
# Traverse all adjacent nodes of u
for ind, node in enumerate(graph[u]):
if visited[ind] is False and node > 0:
queue.append(ind)
visited[ind] = True
parent[ind] = u
parents[ind] = u
return visited[sink]

return visited[t]

def ford_fulkerson(graph: list, source: int, sink: int) -> int:
"""
This function returns the maximum flow from source to sink in the given graph.

def ford_fulkerson(graph, source, sink):
# This array is filled by BFS and to store path
CAUTION: This function changes the given graph.

Args:
graph: Adjacency matrix of graph
source: Source
sink: Sink

Returns:
Maximum flow

>>> test_graph = [
... [0, 16, 13, 0, 0, 0],
... [0, 0, 10, 12, 0, 0],
... [0, 4, 0, 0, 14, 0],
... [0, 0, 9, 0, 0, 20],
... [0, 0, 0, 7, 0, 4],
... [0, 0, 0, 0, 0, 0],
... ]
>>> ford_fulkerson(test_graph, 0, 5)
23
"""
# This array is filled by breadth-first search and to store path
parent = [-1] * (len(graph))
max_flow = 0
while bfs(graph, source, sink, parent):
path_flow = float("Inf")

# While there is a path from source to sink
while breadth_first_search(graph, source, sink, parent):
path_flow = int(1e9) # Infinite value
s = sink

while s != source:
# Find the minimum value in select path
# Find the minimum value in the selected path
path_flow = min(path_flow, graph[parent[s]][s])
s = parent[s]

Expand All @@ -45,17 +101,12 @@ def ford_fulkerson(graph, source, sink):
graph[u][v] -= path_flow
graph[v][u] += path_flow
v = parent[v]

return max_flow


graph = [
[0, 16, 13, 0, 0, 0],
[0, 0, 10, 12, 0, 0],
[0, 4, 0, 0, 14, 0],
[0, 0, 9, 0, 0, 20],
[0, 0, 0, 7, 0, 4],
[0, 0, 0, 0, 0, 0],
]
if __name__ == "__main__":
from doctest import testmod

source, sink = 0, 5
print(ford_fulkerson(graph, source, sink))
testmod()
print(f"{ford_fulkerson(graph, source=0, sink=5) = }")