1+ #include " ../Headers/0003_Graph/0019_MaximumFlowRelabelToFront.h"
2+ #include < climits>
3+ #include < iterator>
4+ using namespace std ;
5+
6+ namespace MaximumFlowRelabelToFront
7+ {
8+ // Graph Private Member Methods
9+
10+ // Initializes Pre-Flow in the given Flow Network
11+ void Graph::InitializePreflow ()
12+ {
13+ // The height of source is set to highest possible height value
14+ this ->_height [this ->_source ] = this ->_noOfVertices ;
15+
16+ // Iterating over all the vertices
17+ for (int i = 0 ; i < this ->_noOfVertices ; i++)
18+ {
19+ // For the all the edges (source, v)
20+ if (this ->_residualGraph [this ->_source ][i] > 0 )
21+ {
22+ // v.excessFlow = capacity(source, v)
23+ this ->_excessFlow [i] = this ->_residualGraph [this ->_source ][i];
24+
25+ // source.excessFlow = source.excessFlow - capacity(source, v)
26+ this ->_excessFlow [this ->_source ] = this ->_excessFlow [this ->_source ] - this ->_residualGraph [this ->_source ][i];
27+
28+ // Adjusting the flow and reverse flow along source->v and v->source respectively
29+ this ->_residualGraph [i][this ->_source ] = this ->_residualGraph [this ->_source ][i];
30+ this ->_residualGraph [this ->_source ][i] = 0 ;
31+ }
32+ }
33+ }
34+
35+ // Discharges the excess flow from nodeU
36+ void Graph::Discharge (int nodeU)
37+ {
38+ // Check if excess flow of nodeU is > 0
39+ while (this ->_excessFlow [nodeU] > 0 )
40+ {
41+ // Falg to check if any amount of excess flow is pushed to any neighbour vertex
42+ bool hasPushed = false ;
43+
44+ // Iterating over all of the vertices
45+ for (int nodeV = 0 ; nodeV < this ->_noOfVertices ; nodeV++)
46+ {
47+ // For G'.Adj[nodeU] check if edge (nodeU, nodeV) is admissible
48+ if (this ->_residualGraph [nodeU][nodeV] > 0 && this ->_height [nodeU] == 1 + this ->_height [nodeV])
49+ {
50+ // Push excess flow along the admissible edge (nodeU, nodeV)
51+ this ->Push (nodeU, nodeV);
52+ // Set the hasPushed flag to true
53+ hasPushed = true ;
54+ // Check if there is no excess flow left in nodeU then no need to check any more admissible edge going from nodeU
55+ if (this ->_excessFlow [nodeU] == 0 )
56+ {
57+ // Then break from iterating over G'.Adj[nodeU]
58+ break ;
59+ }
60+ }
61+ }
62+
63+ // Check if Push operation is not done yet
64+ if (!hasPushed)
65+ {
66+ // Then it indicates that all the outgoing edges from nodeU are inadmissible
67+ // so perform the Relabel operation on nodeU
68+ this ->Relabel (nodeU);
69+ }
70+ }
71+ }
72+
73+ // Pushes the flow from nodeU to its neighbour vertices
74+ void Graph::Push (int nodeU, int nodeV)
75+ {
76+ // Calculate the flow amount to be added along the edge and excess flow subtracted from nodeU
77+ int minimumFlow = min (this ->_residualGraph [nodeU][nodeV], this ->_excessFlow [nodeU]);
78+
79+ // Adjust the flow and the reverse flow along (nodeU, nodeV)
80+ this ->_residualGraph [nodeU][nodeV] = this ->_residualGraph [nodeU][nodeV] - minimumFlow;
81+ this ->_residualGraph [nodeV][nodeU] = this ->_residualGraph [nodeV][nodeU] + minimumFlow;
82+
83+ // Adjust the excess flows in nodeU and nodeV
84+ this ->_excessFlow [nodeU] = this ->_excessFlow [nodeU] - minimumFlow;
85+ this ->_excessFlow [nodeV] = this ->_excessFlow [nodeV] + minimumFlow;
86+ }
87+
88+ // Relabels height of vertex nodeU when there are outgoing non-saturated edges available
89+ void Graph::Relabel (int nodeU)
90+ {
91+ int minimumHeight = INT_MAX;
92+
93+ // Iterating over all the vertices
94+ for (int nodeV = 0 ; nodeV < this ->_noOfVertices ; nodeV++)
95+ {
96+ // For G'.Adj[nodeU] select for which nodeV, height[nodeU] <= height[nodeV]
97+ if (this ->_residualGraph [nodeU][nodeV] > 0 && this ->_height [nodeU] <= this ->_height [nodeV])
98+ {
99+ // Get the minimum height among all these G'.Adj[nodeU]
100+ minimumHeight = min (minimumHeight, this ->_height [nodeV]);
101+ }
102+ }
103+
104+ // Set height[nodeU]
105+ this ->_height [nodeU] = minimumHeight + 1 ;
106+ }
107+
108+
109+ // Graph Public Member Methods
110+ void Graph::CreateGraph (int noOfVertices)
111+ {
112+ this ->_noOfVertices = noOfVertices;
113+ this ->_source = 0 ;
114+ this ->_sink = this ->_noOfVertices - 1 ;
115+ this ->_maximumFlow = 0 ;
116+ this ->_adjMatrix = vector<vector<int >>(this ->_noOfVertices , vector<int >(this ->_noOfVertices , 0 ));
117+ this ->_excessFlow = vector<int >(this ->_noOfVertices , 0 );
118+ this ->_height = vector<int >(this ->_noOfVertices , 0 );
119+ this ->_visited = vector<bool >(this ->_noOfVertices , false );
120+ }
121+
122+ void Graph::PushDirectedEdge (int valueU, int valueV, int capacity)
123+ {
124+ this ->_adjMatrix [valueU][valueV] = capacity;
125+ }
126+
127+ int Graph::FindMaximumFlowRelabelToFront ()
128+ {
129+ this ->_residualGraph = this ->_adjMatrix ;
130+
131+ // Initialize Pre-flow
132+ this ->InitializePreflow ();
133+
134+ // Make the list L = G.V - {source, sink}
135+ for (int i = 0 ; i < this ->_noOfVertices ; i++)
136+ {
137+ if (i != this ->_source && i != this ->_sink )
138+ {
139+ this ->_nodeList .push_back (i);
140+ }
141+ }
142+
143+ // Set current vertex = L.head
144+ list<int >::iterator nodeUiterator = this ->_nodeList .begin ();
145+
146+ // Iterate over all of the elements in the list L
147+ while (nodeUiterator != this ->_nodeList .end ())
148+ {
149+ // Get the height of current vertex
150+ int oldHeight = this ->_height [*nodeUiterator];
151+
152+ // Discharge the excess flow of current vertex
153+ this ->Discharge (*nodeUiterator);
154+
155+ // Check if the height of current vertex increases which means the current vertex got relabeled
156+ if (this ->_height [*nodeUiterator] > oldHeight)
157+ {
158+ // Then move current vertex to the front of the list L
159+ this ->_nodeList .splice (this ->_nodeList .begin (), this ->_nodeList , nodeUiterator);
160+ }
161+
162+ // Go to the next vertex of current vertex in L
163+ nodeUiterator++;
164+ }
165+
166+ // Return the excess flow in the sink vertex which is actually the maximum flow along the given flow network
167+ return this ->_excessFlow [this ->_sink ];
168+ }
169+ }
0 commit comments