Skip to main content

Maximum Flow


PROBLEM DESCRIPTION

The problem of finding the maximum flow in a network, has a history which dates back to the second world war.

Practically the maximum flow problem can be stated as: 
“A list of pipes is given, with different flow-capacities. These pipes are connected at their endpoints. What is the maximum amount of water that you can route from a given starting point to a given ending point?” or equivalently “A company owns a factory located in city X where products are manufactured that need to be transported to the distribution center in city Y. You are given the one-way roads that connect pairs of cities in the country, and the maximum number of trucks that can drive along each road. What is the maximum number of trucks that the company can send to the distribution center?”

Formally stated the problem is:
We are given a network - a directed graph, in which every edge has a certain capacity c associated with it, a starting vertex (called the source), and an ending vertex (called the sink). We are asked to associate another value f(called the flow) for each edge such that for every vertex other than the source and the sink, the sum of the values associated to the edges that enter it must equal the sum of the values associated to the edges that leave it. Furthermore, we are asked to maximize the sum of the values associated to the arcs leaving the source, which is the total flow in the network (which is the same as the sum of the arcs flowing into the sink).

CONSTRAINTS

A flow in the network will have the following constraints:
1) Fi <= Cfor all i ∈ Edges of the network
2) Flow in = Flow out ∀ Vertices ≠ s (source), t (sink)

The first constraint states that the flow on an edge should not exceed it's capacity.
The second constraint states that the flow into any vertex should equal the flow outside the vertex for all vertex except the source and the sink.

REPRESENTATION

So the network looks something like this:

                           http://i42.tinypic.com/2zfjt45.png

                                                                                   Figure 1

The representation a/b on every edge represents the flow/capacity for that particular edge. The flow in the network can be calculated as the total flow leaving the source i.e 3+2 = 5 in the above example. Obviously, the above two constraints must be followed for the flow to be a valid flow.

RESIDUAL GRAPH

Now we define the concept of residual graph.

The residual graph of graph G is denoted by Gf and is constructed by using the following two rules for every edge in G:
1) For every edge with flow fi in G draw a forward edge with capacity ci - fi in Gf. This is also called the residual flow.
2) For every edge with flow fi in G draw a backward edge with capacity fi in Gf. This is also called the backward flow. The main purpose of this edge is to undo the flow already sent into the network.


                                http://www.cs.yale.edu/homes/aspnes/pinewiki/attachments/MaxFlow/residualGraph2.png

                                                                        Figure 2

In the diagram above, we see a flow network G and it's corresponding residual graph Gf.

MAXIMUM FLOW CONDITION

Now that we have defined a residual graph, we make a statement for the maximum flow in the network.
A flow in the network can be called the maximum flow if and only if, the residual graph corresponding to that flow does not have any s-t path
An s-t path in the graph is a path from the source to the sink which consists only of forward edges with positive residual capacity.
To see why the above statement is true we can try and prove the contrapositive of this statement that: if there is an s-t path in the residual graph then it implies that the current flow is not maximum. This is quite evident as if there exists an s-t path then we can simply push the maximum possible flow along that path thereby increasing the flow.

FORD-FULKERSON ALGORITHM

 The Ford-Fulkerson algorithm consists of the following steps:

Step 1: Find a s-t path in Gf (residual graph) using DFS/BFS.
Step 2: Find the edge having the minimum value in the s-t path chosen in step 1.
Step 3: Push the minimum flow calculated in step 2 along the s-t path.
Step 4: Reconstruct the residual graph from the graph with the updated flow in step 3.
Step 5: If there are no more s-t path in the residual graph then terminate the algorithm.

IMPLEMENTATION

 The implementation of this algorithm is pretty straight forward. Here I provide one using C++ with STL.


 








Comments

Popular posts from this blog

Streaming Algorithms - Lossy Counting

We had a discussion recently in our office on one of the famous  streaming algorithms  known as lossy count. I decided to write down my understanding of it focusing on the space complexity discussion and proving why it works in logarithmic space. This  is the original paper introducing this algorithm and most of the information discussed in this blog is (hopefully) a simplified version of this paper relating to lossy count. Problem Statement There are use cases where you may be receiving a continuous stream of data and you want to know which items in that data stream exceed a certain threshold. The data stream could be really big so you can't store it in memory. Moreover you want to answer queries in real time. So here are the challenges this problem imposes: 1. Need to do it in single pass (time constraint) 2. Limited memory 3. Large volume of data in real-time The above issues warrant the need of a smart counting algorithm. Data stream mining to identify events & patterns can

RSA Encryption System

THE NEED OF ENCRYPTION In today's world where a lot of secured information like our credit card number, passwords etc., travel around the web, the presence of a secure encryption system is almost inevitable. We want a method to encrypt a message, send it over the insecure internet connection and allow only the receiver to be able to decrypt and read the original message. This exact problem was solved by R ivest, S hamir and A dleman(RSA) in the year 1978, in their paper A Method for Obtaining Digital Signatures and Public-Key Cryptosystems. In this post, I will try to explain the method they adopted to create a secure encryption system. PUBLIC KEY CRYPTOSYSTEM A public key cryptosystem has the following properties: 1) D(E(M)) = M, if we decrypt an encrypted message, we should get back the message. 2) Both E and D should be easy to compute, if it takes days to encrypt or decrypt the message, then the cryptosystem is not very useful. 3) By publicly revea

Consistent Hashing

 I have been meaning to write this blog for some time now but somehow kept on postponing (read procrastinating...). I read about this technique of Consistent Hashing a while back and was mesmerized by its elegance. Recently read it again in this brilliant blog and thought of expressing it in my own words for posterity. So let us begin. Hashing I won't talk too much about hashing since it is a very basic computer science concept. In a word, it means mapping an object to another object. Or more generally, mapping a key to a value where their types don't matter. Mostly the mapping is from a string to int.  There could be multiple different hash functions that can exist which randomize the how the keys are hashed to the values. We are going to consider a simple use case where let's say you have N different servers and there are multiple keys that you want to distribute among those servers. How do you do it? Well, a simple strategy is that you have a function which applies some