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