From c04d093a0f485dd4d6873f1b7e067cb09ecf4a92 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Tue, 24 Oct 2023 18:11:31 +0530 Subject: [PATCH 1/8] Add function docstrings, comments and type hints --- networking_flow/ford_fulkerson.py | 42 ++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/networking_flow/ford_fulkerson.py b/networking_flow/ford_fulkerson.py index 716ed508e679..e9b61b636863 100644 --- a/networking_flow/ford_fulkerson.py +++ b/networking_flow/ford_fulkerson.py @@ -6,15 +6,32 @@ """ -def bfs(graph, s, t, parent): - # Return True if there is node that has not iterated. - visited = [False] * len(graph) - queue = [] +def bfs(graph: list, s: int, t: int, parent: list) -> bool: + """ + This function returns True if there is node that has not iterated. + + Args: + graph (list): Adjacency matrix of graph + s (int): Source + t (int): Sink + parent (list): Parent list + + Returns: + bool: True if there is node that has not iterated. + """ + + visited = [False] * len(graph) # Mark all nodes as not visited + queue = [] # BFS queue + + # Source node queue.append(s) visited[s] = True while queue: + # Pop the front node u = queue.pop(0) + + # Traverse all adjacent nodes of u for ind in range(len(graph[u])): if visited[ind] is False and graph[u][ind] > 0: queue.append(ind) @@ -24,11 +41,23 @@ def bfs(graph, s, t, parent): return visited[t] -def ford_fulkerson(graph, source, sink): +def ford_fulkerson(graph: list, source: int, sink: int) -> int: + """ + This function returns maximum flow from source to sink in given graph. + + Args: + graph (list): Adjacency matrix of graph + source (int): Source + sink (int): Sink + + Returns: + int: Maximum flow + """ + # This array is filled by BFS and to store path parent = [-1] * (len(graph)) max_flow = 0 - while bfs(graph, source, sink, parent): + while bfs(graph, source, sink, parent): # While there is path from source to sink path_flow = float("Inf") s = sink @@ -45,6 +74,7 @@ def ford_fulkerson(graph, source, sink): graph[u][v] -= path_flow graph[v][u] += path_flow v = parent[v] + return max_flow From dbafd03a5d2a8c4bfd1a9143d86283a68b28e1ed Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Tue, 24 Oct 2023 18:15:49 +0530 Subject: [PATCH 2/8] Fix type mismatch --- networking_flow/ford_fulkerson.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking_flow/ford_fulkerson.py b/networking_flow/ford_fulkerson.py index e9b61b636863..ab2588a9e227 100644 --- a/networking_flow/ford_fulkerson.py +++ b/networking_flow/ford_fulkerson.py @@ -75,7 +75,7 @@ def ford_fulkerson(graph: list, source: int, sink: int) -> int: graph[v][u] += path_flow v = parent[v] - return max_flow + return int(max_flow) # Cast max_flow to int to fix the type mismatch issue graph = [ From 56c44568d741de9dca28424c1af0913f82cadeb1 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Tue, 24 Oct 2023 18:18:45 +0530 Subject: [PATCH 3/8] Fix type hint error --- networking_flow/ford_fulkerson.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/networking_flow/ford_fulkerson.py b/networking_flow/ford_fulkerson.py index ab2588a9e227..76855a4fcb29 100644 --- a/networking_flow/ford_fulkerson.py +++ b/networking_flow/ford_fulkerson.py @@ -58,7 +58,7 @@ def ford_fulkerson(graph: list, source: int, sink: int) -> int: parent = [-1] * (len(graph)) max_flow = 0 while bfs(graph, source, sink, parent): # While there is path from source to sink - path_flow = float("Inf") + path_flow = 1e9 # Infinite value s = sink while s != source: @@ -75,7 +75,7 @@ def ford_fulkerson(graph: list, source: int, sink: int) -> int: graph[v][u] += path_flow v = parent[v] - return int(max_flow) # Cast max_flow to int to fix the type mismatch issue + return max_flow graph = [ From 4366cb00ae3e61e77075f93065ed43e2bcc1672f Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Tue, 24 Oct 2023 18:19:52 +0530 Subject: [PATCH 4/8] Fix float to int error --- networking_flow/ford_fulkerson.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking_flow/ford_fulkerson.py b/networking_flow/ford_fulkerson.py index 76855a4fcb29..674685a14b65 100644 --- a/networking_flow/ford_fulkerson.py +++ b/networking_flow/ford_fulkerson.py @@ -58,7 +58,7 @@ def ford_fulkerson(graph: list, source: int, sink: int) -> int: parent = [-1] * (len(graph)) max_flow = 0 while bfs(graph, source, sink, parent): # While there is path from source to sink - path_flow = 1e9 # Infinite value + path_flow = int(1e9) # Infinite value s = sink while s != source: From 518760364eeb2a7b19ff9324403472ac2f4ea0cb Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 24 Oct 2023 23:20:27 +0200 Subject: [PATCH 5/8] Update ford_fulkerson.py --- networking_flow/ford_fulkerson.py | 73 +++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/networking_flow/ford_fulkerson.py b/networking_flow/ford_fulkerson.py index 674685a14b65..9f7924f1b10d 100644 --- a/networking_flow/ford_fulkerson.py +++ b/networking_flow/ford_fulkerson.py @@ -1,50 +1,69 @@ -# 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; """ +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 bfs(graph: list, s: int, t: int, parent: list) -> bool: +def breadth_first_search(graph: list, source: int, sink: int, parents: list) -> bool: """ This function returns True if there is node that has not iterated. Args: - graph (list): Adjacency matrix of graph - s (int): Source - t (int): Sink - parent (list): Parent list + graph: Adjacency matrix of graph + source: Source + sink: Sink + parents: Parent list Returns: bool: True if there is 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 = [] # BFS queue # Source node - queue.append(s) - visited[s] = True + queue.append(source) + visited[source] = True while queue: # Pop the front node u = queue.pop(0) # Traverse all adjacent nodes of u - for ind in range(len(graph[u])): - if visited[ind] is False and graph[u][ind] > 0: + 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[t] + return visited[sink] def ford_fulkerson(graph: list, source: int, sink: int) -> int: """ This function returns maximum flow from source to sink in given graph. + CAUTION: This function changes the given graph. + Args: graph (list): Adjacency matrix of graph source (int): Source @@ -52,12 +71,24 @@ def ford_fulkerson(graph: list, source: int, sink: int) -> int: Returns: int: 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 BFS and to store path + # 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): # While there is path from source to sink + # While there is path from source to sink + while breadth_first_search(graph, source, sink, parent): path_flow = int(1e9) # Infinite value s = sink @@ -78,14 +109,8 @@ def ford_fulkerson(graph: list, source: int, sink: int) -> int: 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) = }") From b04e9d72181b70beb50f42377438b6e32dc2e71a Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 24 Oct 2023 23:29:51 +0200 Subject: [PATCH 6/8] Update ford_fulkerson.py --- networking_flow/ford_fulkerson.py | 34 ++++++++++++++----------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/networking_flow/ford_fulkerson.py b/networking_flow/ford_fulkerson.py index 9f7924f1b10d..c111a034537f 100644 --- a/networking_flow/ford_fulkerson.py +++ b/networking_flow/ford_fulkerson.py @@ -3,8 +3,8 @@ * 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], @@ -18,7 +18,7 @@ def breadth_first_search(graph: list, source: int, sink: int, parents: list) -> bool: """ - This function returns True if there is node that has not iterated. + This function returns True if there is a node that has not iterated. Args: graph: Adjacency matrix of graph @@ -27,7 +27,7 @@ def breadth_first_search(graph: list, source: int, sink: int, parents: list) -> parents: Parent list Returns: - bool: True if there is node that has not iterated. + True if there is a node that has not iterated. >>> breadth_first_search(graph, 0, 5, [-1, -1, -1, -1, -1, -1]) True @@ -36,41 +36,37 @@ def breadth_first_search(graph: list, source: int, sink: int, parents: list) -> ... IndexError: list index out of range """ - visited = [False] * len(graph) # Mark all nodes as not visited - queue = [] # BFS queue + queue = [] # breadth-first search queue # Source node queue.append(source) visited[source] = True while queue: - # Pop the front node - u = queue.pop(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 parents[ind] = u - return visited[sink] def ford_fulkerson(graph: list, source: int, sink: int) -> int: """ - This function returns maximum flow from source to sink in given graph. + This function returns the maximum flow from source to sink in the given graph. CAUTION: This function changes the given graph. Args: - graph (list): Adjacency matrix of graph - source (int): Source - sink (int): Sink + graph: Adjacency matrix of graph + source: Source + sink: Sink Returns: - int: Maximum flow + Maximum flow >>> test_graph = [ ... [0, 16, 13, 0, 0, 0], @@ -83,17 +79,17 @@ def ford_fulkerson(graph: list, source: int, sink: int) -> int: >>> ford_fulkerson(test_graph, 0, 5) 23 """ - - # This array is filled by breadth first search and to store path + # This array is filled by breadth-first search and to store path parent = [-1] * (len(graph)) max_flow = 0 - # While there is path from source to sink + + # 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] From 3321aeb335828a26c4b90b95e7069af9db494342 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 21:30:19 +0000 Subject: [PATCH 7/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- networking_flow/ford_fulkerson.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking_flow/ford_fulkerson.py b/networking_flow/ford_fulkerson.py index c111a034537f..471bfae371b8 100644 --- a/networking_flow/ford_fulkerson.py +++ b/networking_flow/ford_fulkerson.py @@ -82,7 +82,7 @@ def ford_fulkerson(graph: list, source: int, sink: int) -> int: # This array is filled by breadth-first search and to store path parent = [-1] * (len(graph)) max_flow = 0 - + # While there is a path from source to sink while breadth_first_search(graph, source, sink, parent): path_flow = int(1e9) # Infinite value From 07a9e86542556dd53ff63a824da200c5487ad3bc Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 24 Oct 2023 23:31:04 +0200 Subject: [PATCH 8/8] Update ford_fulkerson.py --- networking_flow/ford_fulkerson.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking_flow/ford_fulkerson.py b/networking_flow/ford_fulkerson.py index 471bfae371b8..7d5fb522e012 100644 --- a/networking_flow/ford_fulkerson.py +++ b/networking_flow/ford_fulkerson.py @@ -44,7 +44,7 @@ def breadth_first_search(graph: list, source: int, sink: int, parents: list) -> visited[source] = True while queue: - u = queue.pop(0). # Pop the front node + 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: