Find minimum s-t cut in a flow network in C++

C++Server Side ProgrammingProgramming

Concept

With respect of a flow network, an s-t cut is denoted as a cut that requires the source ‘s’ and the sink ‘t’ to be in different subsets, and it includes edges going from the source’s side to the sink’s side. Here, the capacity of an s-t cut is denoted by the sum of each edge capacity in the cut-set. Now, the problem discussed here is to determine minimum capacity s-t cut of the given network. Finally, expected output is all edges of the minimum cut.

Here, for example, in the below flow network, example s-t cuts are {{0 ,1}, {0, 2}}, {{0, 2}, {1, 2}, {1, 3}}, etc. The minimum s-t cut is {{1, 3}, {4, 3}, {4 5}} which has capacity as 13+8+5 = 26.

Method

Minimum Cut and Maximum Flow

This is another problem, like Maximum Bipartite Matching, which can solved implementing Ford- Fulkerson Algorithm.

The following is simple idea of Ford-Fulkerson Algorithm

  • Begin with initial flow as 0.
  • While there exists a augmenting path from source to sink.
    • Add this path-flow to flow.
  • Return flow.

Here, Minimum Cut and Maximum Flow problem is based on max − flow min − cut theorem. According to the max − flow min-cut theorem, in a flow network, the amount of maximum flow is equal to capacity of the minimum cut.

Here, from Ford-Fulkerson, we obtain capacity of minimum cut. Now the question is arisenhow to display or print all edges that form the minimum cut. Here, the concept is to implement residual graph. We know that Residual Graph of a flow network is defined as a graph which indicates additional possible flow. It has been observed that if there is a path from source to sink in residual graph, then possibility of addition of flow is done.

Below are steps to print all edges of the minimum cut.

  • We run Ford-Fulkerson algorithm and consider the final residual graph.

  • Determine the set of vertices that are reachable from the source in the residual graph.

  • Now we can conclude that all edges which are from a reachable vertex to non-reachable vertex are minimum cut edges. Print all such edges.

Example

 Live Demo

// C++ program for finding minimum cut using Ford-Fulkerson
#include <iostream>
#include <limits.h>
#include <string.h>
#include <queue>
using namespace std;
// Shows number of vertices in given graph
#define V1 6
/* Now returns true if there is a path from source 's1' to sink
't1' in
residual graph. Also fills parent1[] to store the path */
int bfs(int rGraph1[V1][V1], int s1, int t1, int parent1[]){
   // Build a visited array and mark all vertices as not visited
   bool visited1[V1];
   memset(visited1, 0, sizeof(visited1));
   // Build a queue, enqueue source vertex and mark source vertex
   // as visited
   queue <int> q1;
   q1.push(s1);
   visited1[s1] = true;
   parent1[s1] = -1;
   // Shows standard BFS Loop
   while (!q1.empty()){
      int u1 = q1.front();
      q1.pop();
      for (int v1=0; v1<V1; v1++){
         if (visited1[v1]==false && rGraph1[u1][v1] > 0){
            q1.push(v1);
            parent1[v1] = u1;
            visited1[v1] = true;
         }
      }
   }
   // It has been seen that if we reached sink in BFS starting
   //from source,
   //then return true, else false
   return (visited1[t1] == true);
}
/*Shows a DFS(Depth First Search) based function to find all
reachable
vertices from s. The function marks visited[i] as true if i is
reachable from s. The initial values in visited[] must be false.
We can also use BFS to determine reachable vertices */
void dfs(int rGraph1[V1][V1], int s1, bool visited1[]){
   visited1[s1] = true;
   for (int i = 0; i < V1; i++)
      if (rGraph1[s1][i] && !visited1[i])
   dfs(rGraph1, i, visited1);
}
// Now prints the minimum s-t cut
void minCut(int graph1[V1][V1], int s1, int t1){
   int u1, v1;
   // Build a residual graph and fill the residual graph with
   // given capacities in the original graph as residual capacities
   // in residual graph
   int rGraph1[V1][V1]; // rGraph1[i][j] indicates residual
   // capacity of edge i-j
   for (u1 = 0; u1 < V1; u1++)
      for (v1 = 0; v1 < V1; v1++)
         rGraph1[u1][v1] = graph1[u1][v1];
   int parent1[V1]; // This array is filled by BFS and to store
   //path
   // Now augment the flow while there is a path from source to
   //sink
   while (bfs(rGraph1, s1, t1, parent1)){
      // Determine minimum residual capacity of the edges along
      //the
      // path filled by BFS(Breadth First Search) or we can say determine the maximum flow through the path found.
      int path_flow1 = INT_MAX;
      for (v1=t1; v1!=s1; v1=parent1[v1]){
         u1 = parent1[v1];
         path_flow1 = min(path_flow1, rGraph1[u1][v1]);
      }
      // Perform update residual capacities of the edges and
      //reverse edges along the path
      for (v1=t1; v1 != s1; v1=parent1[v1]){
         u1 = parent1[v1];
         rGraph1[u1][v1] -= path_flow1;
         rGraph1[v1][u1] += path_flow1;
      }
   }
   // Here, flow is maximum now, determine vertices reachable from
   //s
   bool visited1[V1];
   memset(visited1, false, sizeof(visited1));
   dfs(rGraph1, s1, visited1);
   // Now print all edges that are from a reachable vertex to
   // non-reachable vertex in the original graph
   for (int i = 0; i < V1; i++)
      for (int j = 0; j < V1; j++)
         if (visited1[i] && !visited1[j] && graph1[i][j])
   cout << i << " - " << j << endl;
   return;
}
// Driver program to test above functions
int main(){
   // Assuming create a graph shown in the above example
   int graph1[V1][V1] = { {0, 17, 14, 0, 0, 0},{0, 0, 11, 13, 0, 0},{0, 5, 0, 0, 15, 0},
{0, 0, 9, 0, 0, 21},{0, 0, 0, 8, 0, 5},{0, 0, 0, 0, 0, 0}};
   minCut(graph1, 0, 5);
   return 0;
}

Output

1 - 3
4 - 3
4 - 5
raja
Published on 25-Jul-2020 12:57:16
Advertisements