.
5 Runs the highest label variant of the preflow push algorithm with
6 running time O(n^2\sqrt(m)).
10 void run() : runs the algorithm
12 The following functions should be used after run() was already run.
14 T maxflow() : returns the value of a maximum flow
16 T flowonEdge(Edge_iterator e) : for a fixed maximum flow x it returns x(e)
18 EdgeMap<graph_type, T> allflow() : returns the fixed maximum flow x
20 NodeMap<graph_type, bool> mincut() : returns a
21 characteristic vector of a minimum cut. (An empty level
22 in the algorithm gives a minimum cut.)
25 #ifndef PREFLOW_PUSH_HL_H
26 #define PREFLOW_PUSH_HL_H
32 #include <reverse_bfs.hh>
36 template <typename Graph, typename T, typename FlowMap, typename CapacityMap>
37 class preflow_push_hl {
39 typedef typename Graph::NodeIt NodeIt;
40 typedef typename Graph::EdgeIt EdgeIt;
41 typedef typename Graph::EachNodeIt EachNodeIt;
42 typedef typename Graph::OutEdgeIt OutEdgeIt;
43 typedef typename Graph::InEdgeIt InEdgeIt;
44 typedef typename Graph::EachEdgeIt EachEdgeIt;
50 Graph::EdgeMap<T> flow;
51 Graph::EdgeMap<T> capacity;
53 Graph::NodeMap<bool> mincutvector;
58 preflow_push_hl(Graph& _G, NodeIt _s, NodeIt _t,
59 Graph::EdgeMap<T>& _capacity) :
60 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity), mincutvector(_G, true) { }
66 The run() function runs the highest label preflow-push,
67 running time: O(n^2\sqrt(m))
71 Graph::NodeMap<int> level(G); //level of Node
72 Graph::NodeMap<T> excess(G); //excess of Node
74 int n=G.nodeNum(); //number of Nodes
76 /*b is a bound on the highest level of an active Node. In the beginning it is at most n-2.*/
78 std::vector<std::stack<NodeIt> > stack(2*n-1); //Stack of the active Nodes in level i.
83 /*Reverse_bfs from t, to find the starting level.*/
85 reverse_bfs<list_graph> bfs(G, t);
87 for(EachNodeIt v=G.template first<EachNodeIt>(); v.valid(); ++v) {
88 level.set(v, bfs.dist(v));
89 //std::cout << "the level of " << v << " is " << bfs.dist(v);
92 /*The level of s is fixed to n*/
99 /* Starting flow. It is everywhere 0 at the moment. */
101 for(OutEdgeIt i=G.template first<OutEdgeIt>(s); i.valid(); ++i)
104 flow.set(i, capacity.get(i));
105 stack[bfs.dist(w)].push(w);
106 excess.set(w, capacity.get(i));
117 Push/relabel on the highest level active Nodes.
120 /*While there exists active Node.*/
123 /*We decrease the bound if there is no active Node of level b.*/
124 if (stack[b].empty()) {
128 NodeIt w=stack[b].top(); //w is the highest label active Node.
129 stack[b].pop(); //We delete w from the stack.
131 int newlevel=2*n-2; //In newlevel we maintain the next level of w.
133 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
135 /*e is the Edge wv.*/
137 if (flow.get(e)<capacity.get(e)) {
138 /*e is an Edge of the residual graph */
140 if(level.get(w)==level.get(v)+1) {
141 /*Push is allowed now*/
143 if (capacity.get(e)-flow.get(e) > excess.get(w)) {
144 /*A nonsaturating push.*/
146 if (excess.get(v)==0 && v != s) stack[level.get(v)].push(v);
147 /*v becomes active.*/
149 flow.set(e, flow.get(e)+excess.get(w));
150 excess.set(v, excess.get(v)+excess.get(w));
152 //std::cout << w << " " << v <<" elore elen nonsat pump " << std::endl;
155 /*A saturating push.*/
157 if (excess.get(v)==0 && v != s) stack[level.get(v)].push(v);
158 /*v becomes active.*/
160 excess.set(v, excess.get(v)+capacity.get(e)-flow.get(e));
161 excess.set(w, excess.get(w)-capacity.get(e)+flow.get(e));
162 flow.set(e, capacity.get(e));
163 //std::cout << w<<" " <<v<<" elore elen sat pump " << std::endl;
164 if (excess.get(w)==0) break;
165 /*If w is not active any more, then we go on to the next Node.*/
167 } // if (capacity.get(e)-flow.get(e) > excess.get(w))
168 } // if(level.get(w)==level.get(v)+1)
170 else {newlevel = newlevel < level.get(v) ? newlevel : level.get(v);}
172 } //if (flow.get(e)<capacity.get(e))
174 } //for(OutEdgeIt e=G.first_OutEdge(w); e.valid(); ++e)
178 for(InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
180 /*e is the Edge vw.*/
182 if (excess.get(w)==0) break;
183 /*It may happen, that w became inactive in the first for cycle.*/
185 /*e is an Edge of the residual graph */
187 if(level.get(w)==level.get(v)+1) {
188 /*Push is allowed now*/
190 if (flow.get(e) > excess.get(w)) {
191 /*A nonsaturating push.*/
193 if (excess.get(v)==0 && v != s) stack[level.get(v)].push(v);
194 /*v becomes active.*/
196 flow.set(e, flow.get(e)-excess.get(w));
197 excess.set(v, excess.get(v)+excess.get(w));
199 //std::cout << v << " " << w << " vissza elen nonsat pump " << std::endl;
202 /*A saturating push.*/
204 if (excess.get(v)==0 && v != s) stack[level.get(v)].push(v);
205 /*v becomes active.*/
207 excess.set(v, excess.get(v)+flow.get(e));
208 excess.set(w, excess.get(w)-flow.get(e));
210 //std::cout << v <<" " << w << " vissza elen sat pump " << std::endl;
211 if (excess.get(w)==0) { break;}
212 } //if (flow.get(e) > excess.get(v))
213 } //if(level.get(w)==level.get(v)+1)
215 else {newlevel = newlevel < level.get(v) ? newlevel : level.get(v);}
218 } //if (flow.get(e)>0)
223 if (excess.get(w)>0) {
224 level.set(w,++newlevel);
225 stack[newlevel].push(w);
227 //std::cout << "The new level of " << w << " is "<< newlevel <<std::endl;
235 value = excess.get(t);
248 Returns the maximum value of a flow.
258 For the maximum flow x found by the algorithm, it returns the flow value on Edge e, i.e. x(e).
261 T flowonEdge(EdgeIt e) {
268 Returns the maximum flow x found by the algorithm.
271 EdgeMap<graph_type, T> allflow() {
278 Returns a minimum cut by using a reverse bfs from t in the residual graph.
281 NodeMap<graph_type, bool> mincut() {
283 std::queue<NodeIt> queue;
285 mincutvector.set(t,false);
288 while (!queue.empty()) {
289 NodeIt w=queue.front();
292 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
294 if (mincutvector.get(v) && flow.get(e) < capacity.get(e) ) {
296 mincutvector.set(v, false);
300 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
302 if (mincutvector.get(v) && flow.get(e) > 0 ) {
304 mincutvector.set(v, false);