Download as pdf or txt
Download as pdf or txt
You are on page 1of 39

[Document title]

BCSE204L:Design and Analysis of


Algorithms Lab
SLOT: L29+L30
FALL SEMESTER 2022-2023
Date:05-04-2023
Class Number: VL2022230504106
Faculty in charge: VISHNU SRINIVASA MURTHY Y

Submitted by:
NAME: A MANOJ SAI
Reg No: 21BDS0224
B.Tech : 2nd Year
Name of School: Scope

1 | Page
[Document title]

1. A pipeline network is essential to transmit water, goods,


or other essentials through it. However, each pipe is having
its own capacity and flow value. The pipelines are
connected through many intermediate nodes. As a
computational engineer, it is essential to develop an
automated tool that could compute the maximum flow that
can be obtained through network using various algorithms.
However, Ford-Fulkerson and Edmond Karp are two popular
researchers who invented a similar approach using two
different supporting data structures called stack and queue
respectively.
Develop both the algorithms for three different graphs of at
least nine vertices in each. Fill the
following table accordingly.

Code:
Ford-Fulkerson Approach:
For Graph 1:

#include <iostream>

2 | Page
[Document title]

#include <string.h>
using namespace std;
#define N 10
#define INF 9999999
int Flow[N][N];
bool visited[N];

int graph[N][N] = {
{ 0, 6, 0, 0, 0, 6, 0, 0, 2, 0}, //s
{ 0, 0, 3, 0, 0, 3, 0, 0, 0, 0}, //a
{ 0, 0, 0, 2, 0, 6, 0, 3, 0, 0 }, //b
{ 0, 0, 0, 0, 4, 0, 0, 0, 0, 0}, //c
{ 0, 0, 0, 0, 0, 0, 0, 4, 0, 7}, //d
{ 0, 0, 0, 0, 0, 0, 3, 0, 2, 0}, //e
{ 0, 0, 0, 0, 0, 0, 0, 2, 1, 0}, //f
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3}, //g
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6}, //h
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //t
};
int min(int a,int b)

3 | Page
[Document title]

{
if(a<b)
return a;
else
return b;
}
int dfs(int s, int t, int minimum) {
visited[s] = true;
if (s == t)
return minimum;
for (int i = 0; i < N; i++) {
int flow_capacity = graph[s][i] - Flow[s][i];
if (!visited[i] && flow_capacity > 0) {
if (int sent = dfs (i, t, min(minimum, flow_capacity))) {
Flow[s][i] += sent;
Flow[i][s] -= sent;
return sent;
}
}
}

4 | Page
[Document title]

return false;
}
int main() {
memset(Flow, 0, sizeof(Flow));
memset(visited, 0, sizeof(visited));
int s = 0;
int t = 9;
int max_flow = 0;
while (int sent = dfs(s, t, INF)) {
max_flow += sent;
memset(visited, 0, sizeof(visited));
}
printf("The max flow from node %d to sink node %d is
%d",s,t,max_flow);
}
Output:

5 | Page
[Document title]

For Graph 2:
#include <iostream>
#include <string.h>
using namespace std;
#define N 9
#define INF 9999999
int Flow[N][N];
bool visited[N];

int graph[N][N] = {
{ 0, 26, 17, 0, 37,0, 0, 0, 0}, //s
{ 0, 0, 0, 20, 10, 0, 0, 0, 0}, //a
{ 0, 0, 0, 0, 20, 15, 0, 3, 0}, //b
{ 0, 0, 0, 0, 0, 10, 22, 18,0}, //c
{ 0, 0, 0, 35, 0, 15, 0, 0, 0}, //d
{ 0, 0, 0, 0, 0, 0, 0, 34, 0}, //e
{ 0, 0, 0, 0, 0, 0, 0, 0, 48}, //f
{ 0, 0, 0, 0, 0, 0, 20, 0, 30}, //g
{ 0, 0, 0, 0, 0, 0, 0, 0, 0}, //t
};

6 | Page
[Document title]

int min(int a,int b)


{
if(a<b)
return a;
else
return b;
}
int dfs(int s, int t, int minimum) {
visited[s] = true;
if (s == t)
return minimum;
for (int i = 0; i < N; i++) {
int flow_capacity = graph[s][i] - Flow[s][i];
if (!visited[i] && flow_capacity > 0) {
if (int sent = dfs (i, t, min(minimum, flow_capacity))) {
Flow[s][i] += sent;
Flow[i][s] -= sent;
return sent;
}
}

7 | Page
[Document title]

}
return false;
}
int main() {
memset(Flow, 0, sizeof(Flow));
memset(visited, 0, sizeof(visited));
int s = 0;
int t = 8;
int max_flow = 0;
while (int sent = dfs(s, t, INF)) {
max_flow += sent;
memset(visited, 0, sizeof(visited));
}
printf("The max flow from node %d to sink node %d is
%d",s,t,max_flow);
}
Output:

8 | Page
[Document title]

For Graph 3:
#include <iostream>
#include <string.h>
using namespace std;
#define N 9
#define INF 9999999
int Flow[N][N];
bool visited[N];

int graph[N][N] = {
{ 0, 26, 17, 0, 37,0, 0, 0, 0}, //s
{ 0, 0, 0, 20, 5, 0, 0, 0, 0}, //a
{ 0, 0, 0, 0, 20, 15, 0, 3, 0}, //b
{ 0, 0, 0, 0, 0, 10, 22, 18,0}, //c
{ 0, 0, 0, 25, 0, 15, 0, 0, 0}, //d
{ 0, 0, 0, 0, 0, 0, 0, 34, 0}, //e
{ 0, 0, 0, 0, 0, 0, 0, 0, 24}, //f
{ 0, 0, 0, 0, 0, 0, 20, 0, 26}, //g
{ 0, 0, 0, 0, 0, 0, 0, 0, 0}, //t
};

9 | Page
[Document title]

int min(int a,int b)


{
if(a<b)
return a;
else
return b;
}
int dfs(int s, int t, int minimum) {
visited[s] = true;
if (s == t)
return minimum;
for (int i = 0; i < N; i++) {
int flow_capacity = graph[s][i] - Flow[s][i];
if (!visited[i] && flow_capacity > 0) {
if (int sent = dfs (i, t, min(minimum, flow_capacity))) {
Flow[s][i] += sent;
Flow[i][s] -= sent;
return sent;
}
}

10 | P a g e
[Document title]

}
return false;
}
int main() {
memset(Flow, 0, sizeof(Flow));
memset(visited, 0, sizeof(visited));
int s = 0;
int t = 8;
int max_flow = 0;
while (int sent = dfs(s, t, INF)) {
max_flow += sent;
memset(visited, 0, sizeof(visited));
}
printf("The max flow from node %d to sink node %d is
%d",s,t,max_flow);
}
Output:

11 | P a g e
[Document title]

Edmond karp Approach:


For Graph 1:
#include<stdio.h>
#include <string.h>
#include <limits.h>
#define V 10

// Returns true if there is a path from source 's' to sink 't' in


residual graph.
// Also fills parent[] to store the path.

12 | P a g e
[Document title]

int bfs(int rGraph[V][V], int s, int t, int parent[]) {


// Create a visited array and initialize all vertices as not
visited.
int visited[V];
memset(visited, 0, sizeof(visited));

// Create a queue, enqueue source vertex and mark source


vertex as visited.
int queue[V];
int front = 0, rear = 0;
queue[rear++] = s;
visited[s] = 1;
parent[s] = -1;

// Standard BFS Loop


while (front < rear) {
int u = queue[front++];
int v;
for ( v = 0; v < V; v++) {
if (visited[v] == 0 && rGraph[u][v] > 0) {

13 | P a g e
[Document title]

queue[rear++] = v;
parent[v] = u;
visited[v] = 1;
}
}
}

// If we can't reach the sink in the BFS starting from the


source, return false.
return (visited[t] == 1);
}

// Returns the maximum flow from source to sink in the given


graph.
int edmonds_karp(int graph[V][V], int s, int t) {
int u, v;

// Create a residual graph and fill the residual graph with


given capacities in the original graph.
int rGraph[V][V];

14 | P a g e
[Document title]

for (u = 0; u < V; u++) {


for (v = 0; v < V; v++) {
rGraph[u][v] = graph[u][v];
}
}

int parent[V]; // This array is filled by BFS and to store path

int max_flow = 0; // There is no flow initially

// Augment the flow while there is path from source to sink


while (bfs(rGraph, s, t, parent)) {
// Find minimum residual capacity of the edges along the
path filled by BFS.
int path_flow = INT_MAX;
for (v = t; v != s; v = parent[v]) {
u = parent[v];
path_flow = path_flow > rGraph[u][v] ? rGraph[u][v] :
path_flow;
}

15 | P a g e
[Document title]

// Update residual capacities of the edges and reverse


edges along the path
for (v = t; v != s; v = parent[v]) {
u = parent[v];
rGraph[u][v] -= path_flow;
rGraph[v][u] += path_flow;
}

// Add path flow to overall flow


max_flow += path_flow;
}

// Return the overall flow


return max_flow;
}

// Driver program to test above functions


int main() {
// Let us create a graph shown in the above example

16 | P a g e
[Document title]

int s=0;
int t=9;
int graph[V][V] = {
{ 0, 6, 0, 0, 0, 6, 0, 0, 2, 0}, //s
{ 0, 0, 3, 0, 0, 3, 0, 0, 0, 0}, //a
{ 0, 0, 0, 2, 0, 6, 0, 3, 0, 0 }, //b
{ 0, 0, 0, 0, 4, 0, 0, 0, 0, 0}, //c
{ 0, 0, 0, 0, 0, 0, 0, 4, 0, 7}, //d
{ 0, 0, 0, 0, 0, 0, 3, 0, 2, 0}, //e
{ 0, 0, 0, 0, 0, 0, 0, 2, 1, 0}, //f
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3}, //g
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6}, //h
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},};
printf("The max flow from node %d to sink node %d is %d",
s,t,edmonds_karp(graph,0,9));
}
Output:

17 | P a g e
[Document title]

For Graph 2:
#include<stdio.h>
#include <string.h>
#include <limits.h>
#define V 9

// Returns true if there is a path from source 's' to sink 't' in


residual graph.
// Also fills parent[] to store the path.
int bfs(int rGraph[V][V], int s, int t, int parent[]) {
// Create a visited array and initialize all vertices as not
visited.
int visited[V];
memset(visited, 0, sizeof(visited));

// Create a queue, enqueue source vertex and mark source


vertex as visited.
int queue[V];

18 | P a g e
[Document title]

int front = 0, rear = 0;


queue[rear++] = s;
visited[s] = 1;
parent[s] = -1;

// Standard BFS Loop


while (front < rear) {
int u = queue[front++];
int v;
for ( v = 0; v < V; v++) {
if (visited[v] == 0 && rGraph[u][v] > 0) {
queue[rear++] = v;
parent[v] = u;
visited[v] = 1;
}
}
}

// If we can't reach the sink in the BFS starting from the


source, return false.

19 | P a g e
[Document title]

return (visited[t] == 1);


}

// Returns the maximum flow from source to sink in the given


graph.
int edmonds_karp(int graph[V][V], int s, int t) {
int u, v;

// Create a residual graph and fill the residual graph with


given capacities in the original graph.
int rGraph[V][V];
for (u = 0; u < V; u++) {
for (v = 0; v < V; v++) {
rGraph[u][v] = graph[u][v];
}
}

int parent[V]; // This array is filled by BFS and to store path

int max_flow = 0; // There is no flow initially

20 | P a g e
[Document title]

// Augment the flow while there is path from source to sink


while (bfs(rGraph, s, t, parent)) {
// Find minimum residual capacity of the edges along the
path filled by BFS.
int path_flow = INT_MAX;
for (v = t; v != s; v = parent[v]) {
u = parent[v];
path_flow = path_flow > rGraph[u][v] ? rGraph[u][v] :
path_flow;
}

// Update residual capacities of the edges and reverse


edges along the path
for (v = t; v != s; v = parent[v]) {
u = parent[v];
rGraph[u][v] -= path_flow;
rGraph[v][u] += path_flow;
}

21 | P a g e
[Document title]

// Add path flow to overall flow


max_flow += path_flow;
}

// Return the overall flow


return max_flow;
}

// Driver program to test above functions


int main() {
// Let us create a graph shown in the above example
int s=0;
int t=8;
int graph[V][V] = {
{ 0, 26, 17, 0, 37,0, 0, 0, 0}, //s
{ 0, 0, 0, 20, 10, 0, 0, 0, 0}, //a
{ 0, 0, 0, 0, 20, 15, 0, 3, 0}, //b
{ 0, 0, 0, 0, 0, 10, 22, 18,0}, //c
{ 0, 0, 0, 35, 0, 15, 0, 0, 0}, //d
{ 0, 0, 0, 0, 0, 0, 0, 34, 0}, //e

22 | P a g e
[Document title]

{ 0, 0, 0, 0, 0, 0, 0, 0, 48}, //f
{ 0, 0, 0, 0, 0, 0, 20, 0, 30}, //g
{ 0, 0, 0, 0, 0, 0, 0, 0, 0}};//t
printf("The max flow from node %d to sink node %d is %d",
s,t,edmonds_karp(graph,0,8));
}
Output:

For Graph 3:
#include<stdio.h>
#include <string.h>
#include <limits.h>
#define V 9

// Returns true if there is a path from source 's' to sink 't' in


residual graph.
// Also fills parent[] to store the path.
int bfs(int rGraph[V][V], int s, int t, int parent[]) {

23 | P a g e
[Document title]

// Create a visited array and initialize all vertices as not


visited.
int visited[V];
memset(visited, 0, sizeof(visited));

// Create a queue, enqueue source vertex and mark source


vertex as visited.
int queue[V];
int front = 0, rear = 0;
queue[rear++] = s;
visited[s] = 1;
parent[s] = -1;

// Standard BFS Loop


while (front < rear) {
int u = queue[front++];
int v;
for ( v = 0; v < V; v++) {
if (visited[v] == 0 && rGraph[u][v] > 0) {
queue[rear++] = v;

24 | P a g e
[Document title]

parent[v] = u;
visited[v] = 1;
}
}
}

// If we can't reach the sink in the BFS starting from the


source, return false.
return (visited[t] == 1);
}

// Returns the maximum flow from source to sink in the given


graph.
int edmonds_karp(int graph[V][V], int s, int t) {
int u, v;

// Create a residual graph and fill the residual graph with


given capacities in the original graph.
int rGraph[V][V];
for (u = 0; u < V; u++) {

25 | P a g e
[Document title]

for (v = 0; v < V; v++) {


rGraph[u][v] = graph[u][v];
}
}

int parent[V]; // This array is filled by BFS and to store path

int max_flow = 0; // There is no flow initially

// Augment the flow while there is path from source to sink


while (bfs(rGraph, s, t, parent)) {
// Find minimum residual capacity of the edges along the
path filled by BFS.
int path_flow = INT_MAX;
for (v = t; v != s; v = parent[v]) {
u = parent[v];
path_flow = path_flow > rGraph[u][v] ? rGraph[u][v] :
path_flow;
}

26 | P a g e
[Document title]

// Update residual capacities of the edges and reverse


edges along the path
for (v = t; v != s; v = parent[v]) {
u = parent[v];
rGraph[u][v] -= path_flow;
rGraph[v][u] += path_flow;
}

// Add path flow to overall flow


max_flow += path_flow;
}

// Return the overall flow


return max_flow;
}

// Driver program to test above functions


int main() {
// Let us create a graph shown in the above example
int s=0;

27 | P a g e
[Document title]

int t=8;
int graph[V][V] = {
{ 0, 26, 17, 0, 37,0, 0, 0, 0}, //s
{ 0, 0, 0, 20, 5, 0, 0, 0, 0}, //a
{ 0, 0, 0, 0, 20, 15, 0, 3, 0}, //b
{ 0, 0, 0, 0, 0, 10, 22, 18,0}, //c
{ 0, 0, 0, 25, 0, 15, 0, 0, 0}, //d
{ 0, 0, 0, 0, 0, 0, 0, 34, 0}, //e
{ 0, 0, 0, 0, 0, 0, 0, 0, 24}, //f
{ 0, 0, 0, 0, 0, 0, 20, 0, 26}, //g
{ 0, 0, 0, 0, 0, 0, 0, 0, 0},//t
};
printf("The max flow from node %d to sink node %d is %d",
s,t,edmonds_karp(graph,0,8));
}
Output:

Comparsion:

28 | P a g e
[Document title]

Algorithm Maximum Flow


Graph1 Graph 2 Graph 3
Ford 10 72 50
Fulkerson
Edmond 10 72 50
Karp

29 | P a g e
[Document title]

30 | P a g e
[Document title]

31 | P a g e
[Document title]

ALL IN ONE CODE :-


#include<iostream>
#include<queue>
#include<cstring>
#include<limits.h>
using namespace std;
#define N 9
bool bfs(int rgraph[N][N],int s,int t,int parent[])
{
bool visited[N];
memset(visited,0,sizeof(visited));
queue<int>q;
q.push(s);
visited[s]=true;
parent[s]=-1;
while(!q.empty())
{
int u=q.front();
q.pop();

32 | P a g e
[Document title]

for(int v=0;v<N;v++)
{
if(visited[v]==false && rgraph[u][v]>0)
{
q.push(v);
parent[v]=u;
visited[v]=true;
}
}
}
return visited[t]==true;
}
int edmondKarp(int G[N][N],int s,int t)
{
int u,v;
int rgraph[N][N];
for(int u=0;u<N;u++)
{
for(int v=0;v<N;v++)
{

33 | P a g e
[Document title]

rgraph[u][v]=G[u][v];
}
}
int parent[N];
int maxflow=0;
while(bfs(rgraph,s,t,parent))
{
int pathflow=INT_MAX;
for(v=t;v!=s;v=parent[v])
{
u=parent[v];
pathflow=min(pathflow,rgraph[u][v]);
}
for(v=t;v!=s;v=parent[v])
{
u=parent[v];
rgraph[u][v]-=pathflow;
rgraph[v][u]+=pathflow;
}
maxflow+=pathflow;

34 | P a g e
[Document title]

}
return maxflow;
}
bool DFS(int rGraph[N][N],int parent[],bool visited[],int
n,int x,int t)
{
if(x == t)
return true;
visited[x] = true;
for(int i=0;i<n;++i)
{
if(rGraph[x][i]>0 && !visited[i])
{
parent[i]=x;
if(DFS(rGraph, parent, visited, n, i, t))
return true;
}
}
return false;
}

35 | P a g e
[Document title]

int fordFulkerson(int G[N][N],int n,int s,int t)


{
int u,v;
int rgraph[N][N];
for(int u=0;u<N;u++)
{
for(int v=0;v<N;v++)
{
rgraph[u][v]=G[u][v];
}
}
int parent[N];
int maxflow=0;
bool visited[N];
while(DFS(rgraph,parent,visited,n,s,t))
{
memset(visited,false,sizeof(visited));
int pathflow=INT_MAX;
for(v=t;v!=s;v=parent[v])
{

36 | P a g e
[Document title]

u=parent[v];
pathflow=min(pathflow,rgraph[u][v]);
}
for(v=t;v!=s;v=parent[v])
{
u=parent[v];
rgraph[u][v]-=pathflow;
rgraph[v][u]+=pathflow;
}
maxflow+=pathflow;
}
return maxflow;
}
int main()
{
int G1[9][9]={{0,26,17,0,37,0,0,0,0},
{0,0,0,20,10,0,0,0,0},
{0,0,0,0,20,15,0,0,},
{0,0,0,0,0,10,22,18,0},
{0,0,0,35,0,15,0,0,0},

37 | P a g e
[Document title]

{0,0,0,0,0,0,0,34,0},
{0,0,0,0,0,0,0,0,48},
{0,0,0,0,0,0,20,0,30},
{0,0,0,0,0,0,0,0,0}};
int G2[9][9]={{0,5,0,5,0,0,0,0,0},
{0,0,3,0,3,0,0,0,0},
{0,0,0,0,0,4,0,0,0},
{0,0,2,0,0,4,0,0,0},
{0,0,0,0,0,0,6,0,0},
{0,0,0,0,0,0,6,0,0},
{0,0,0,0,0,0,0,5,0},
{0,0,0,0,0,0,0,3,3},
{0,0,0,0,0,0,0,0,5}};
int G3[9][9]={{0,9,1,0,10,0,0,0,6},
{0,0,5,3,4,0,0,7,0},
{0,0,0,10,0,0,0,0,0},
{0,4,7,0,5,0,0,0,0},
{0,4,0,10,0,0,0,0,7},
{0,0,5,0,0,0,9,1,0},
{0,1,0,4,0,0,0,5,0},

38 | P a g e
[Document title]

{0,1,6,1,5,0,0,0,5},
{0,0,0,0,0,0,0,0,0}};
cout<<"Ford Fulkerson ";

cout<<fordFulkerson(G1,9,0,8)<<"\t"<<fordFulkerson(G2,9,
0,8)<<"\t"<<fordFulkerson(G3,9,0,8);
cout<<"\nEdmond Karp"<<"\t";

cout<<edmondKarp(G1,0,8)<<"\t"<<edmondKarp(G2,0,8)<<
"\t"<<edmondKarp(G3,0,8);
}

39 | P a g e

You might also like