Skip to content

Add Ford Fulkerson Algorithm #644

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
44 changes: 44 additions & 0 deletions pydatastructs/graphs/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,50 @@ def _breadth_first_search_max_flow(graph: Graph, source_node, sink_node, flow_pa
return (0, parent)


def _copy_graph_with_residual_edges(graph: Graph) -> Graph:
vertices = [graph.__getattribute__(v) for v in graph.vertices]
new_graph = type(graph)(*vertices)
for key, edge in graph.edge_weights.items():
new_graph.add_edge(edge.source.name, edge.target.name, edge.value)
for key, edge in list(new_graph.edge_weights.items()):
src = edge.source.name
tgt = edge.target.name
if new_graph.get_edge(tgt, src) is None:
new_graph.add_edge(tgt, src, 0)
return new_graph


def _dfs_max_flow(graph: Graph, node, sink, flow_passed, visited, flow):
if node == sink:
return flow
visited[node] = True
for next_node in graph.neighbors(node):
capacity = graph.get_edge(node, next_node.name).value
fp = flow_passed.get((node, next_node.name), 0)
residual_capacity = capacity - fp
if residual_capacity > 0 and next_node.name not in visited:
bottleneck_flow = _dfs_max_flow(
graph, next_node.name, sink, flow_passed, visited, min(flow, residual_capacity)
)
if bottleneck_flow > 0:
flow_passed[(node, next_node.name)] = fp + bottleneck_flow
flow_passed[(next_node.name, node)] = flow_passed.get((next_node.name, node), 0) - bottleneck_flow
return bottleneck_flow
return 0

def _max_flow_ford_fulkerson_(graph: Graph, source, sink):
graph_copy = _copy_graph_with_residual_edges(graph)
m_flow = 0
flow_passed = {}
while True:
visited = {}
new_flow = _dfs_max_flow(graph_copy, source, sink, flow_passed, visited, float('inf'))
if new_flow == 0:
break
m_flow += new_flow
return m_flow


def _max_flow_edmonds_karp_(graph: Graph, source, sink):
m_flow = 0
flow_passed = {}
Expand Down
2 changes: 2 additions & 0 deletions pydatastructs/graphs/tests/test_algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,3 +448,5 @@ def _test_max_flow(ds, algorithm):
_test_max_flow("Matrix", "edmonds_karp")
_test_max_flow("List", "dinic")
_test_max_flow("Matrix", "dinic")
_test_max_flow("List", "ford_fulkerson")
_test_max_flow("Matrix", "ford_fulkerson")
Loading