Introduction

Maximum flow algorithms are used to find the maximum possible flow in a flow network. A flow network is a directed graph where each edge has a capacity and each edge receives a flow. The goal is to maximize the flow from a source node to a sink node while respecting the capacities of the edges.

Key Concepts

  1. Flow Network: A directed graph \( G = (V, E) \) where each edge \( (u, v) \in E \) has a non-negative capacity \( c(u, v) \).
  2. Source (s): The node where the flow originates.
  3. Sink (t): The node where the flow is collected.
  4. Flow (f): A function \( f: E \rightarrow \mathbb{R} \) that satisfies:
    • Capacity constraint: \( 0 \leq f(u, v) \leq c(u, v) \) for all \( (u, v) \in E \).
    • Flow conservation: \( \sum_{v \in V} f(u, v) = \sum_{v \in V} f(v, u) \) for all \( u \in V \setminus {s, t} \).

Ford-Fulkerson Algorithm

The Ford-Fulkerson method is a greedy approach to compute the maximum flow in a flow network. It repeatedly finds augmenting paths and increases the flow until no more augmenting paths can be found.

Steps of the Ford-Fulkerson Algorithm

  1. Initialize: Start with zero flow.
  2. Find Augmenting Path: Use Depth-First Search (DFS) or Breadth-First Search (BFS) to find a path from the source \( s \) to the sink \( t \) where the residual capacity is positive.
  3. Augment Flow: Increase the flow along the path found in step 2 by the minimum residual capacity of the edges in the path.
  4. Update Residual Graph: Adjust the capacities of the edges in the residual graph.
  5. Repeat: Repeat steps 2-4 until no more augmenting paths can be found.

Example

Consider the following flow network:

    s
   / \
  10  5
 /     \
a---5---b
 \     /
  5   10
   \ /
    t
  1. Initialize: Start with zero flow.
  2. Find Augmenting Path: \( s \rightarrow a \rightarrow b \rightarrow t \) with a minimum capacity of 5.
  3. Augment Flow: Increase the flow by 5.
  4. Update Residual Graph: Adjust the capacities.

The process continues until no more augmenting paths can be found.

Python Implementation

from collections import defaultdict

class Graph:
    def __init__(self, vertices):
        self.graph = defaultdict(list)
        self.ROW = vertices

    def add_edge(self, u, v, w):
        self.graph[u].append((v, w))

    def bfs(self, s, t, parent):
        visited = [False] * self.ROW
        queue = []
        queue.append(s)
        visited[s] = True

        while queue:
            u = queue.pop(0)

            for v, w in self.graph[u]:
                if visited[v] == False and w > 0:
                    queue.append(v)
                    visited[v] = True
                    parent[v] = u
                    if v == t:
                        return True
        return False

    def ford_fulkerson(self, source, sink):
        parent = [-1] * self.ROW
        max_flow = 0

        while self.bfs(source, sink, parent):
            path_flow = float("Inf")
            s = sink

            while s != source:
                for v, w in self.graph[parent[s]]:
                    if v == s:
                        path_flow = min(path_flow, w)
                s = parent[s]

            max_flow += path_flow

            v = sink
            while v != source:
                u = parent[v]
                for i, (vertex, weight) in enumerate(self.graph[u]):
                    if vertex == v:
                        self.graph[u][i] = (vertex, weight - path_flow)
                for i, (vertex, weight) in enumerate(self.graph[v]):
                    if vertex == u:
                        self.graph[v][i] = (vertex, weight + path_flow)
                v = parent[v]

        return max_flow

# Example usage
g = Graph(4)
g.add_edge(0, 1, 10)
g.add_edge(0, 2, 5)
g.add_edge(1, 2, 5)
g.add_edge(1, 3, 10)
g.add_edge(2, 3, 10)

source = 0
sink = 3

print("The maximum possible flow is %d" % g.ford_fulkerson(source, sink))

Explanation

  1. Graph Initialization: The graph is initialized with vertices and edges.
  2. BFS Function: Finds an augmenting path using BFS.
  3. Ford-Fulkerson Function: Implements the Ford-Fulkerson algorithm to find the maximum flow.

Practical Exercises

Exercise 1

Given the following flow network, find the maximum flow from source \( s \) to sink \( t \):

    s
   / \
  15  10
 /     \
a---5---b
 \     /
  10  15
   \ /
    t

Solution

  1. Initialize: Start with zero flow.
  2. Find Augmenting Path: \( s \rightarrow a \rightarrow t \) with a minimum capacity of 10.
  3. Augment Flow: Increase the flow by 10.
  4. Update Residual Graph: Adjust the capacities.

Repeat the process until no more augmenting paths can be found. The maximum flow is 20.

Exercise 2

Implement the Ford-Fulkerson algorithm for the following graph and find the maximum flow:

    s
   / \
  20  10
 /     \
a---10--b
 \     /
  5   15
   \ /
    t

Solution

g = Graph(4)
g.add_edge(0, 1, 20)
g.add_edge(0, 2, 10)
g.add_edge(1, 2, 10)
g.add_edge(1, 3, 15)
g.add_edge(2, 3, 15)

source = 0
sink = 3

print("The maximum possible flow is %d" % g.ford_fulkerson(source, sink))

The maximum possible flow is 25.

Common Mistakes and Tips

  1. Not Updating Residual Graph Correctly: Ensure that the residual capacities are updated correctly after each augmentation.
  2. Infinite Loop in BFS: Make sure to mark nodes as visited to avoid infinite loops.
  3. Handling Edge Cases: Consider edge cases where there are no augmenting paths or where the capacities are zero.

Conclusion

Maximum flow algorithms are crucial for solving various network flow problems. The Ford-Fulkerson method, with its iterative approach to finding augmenting paths, provides a foundational technique for understanding and implementing these algorithms. By practicing with different flow networks, you can gain a deeper understanding of how to apply these concepts effectively.

© Copyright 2024. All rights reserved