Timer class for measuring user/system time added.
8 list 'level_list' on the nodes on level i implemented by hand
10 relevel: in phase 0, after BFS*n relabels, it runs a reverse
11 bfs from t in the res graph to relevel the nodes reachable from t.
12 BFS is initialized to 20
14 Due to the last heuristic, this algorithm is quite fast on very
15 sparse graphs, but relatively bad on even the dense graphs.
17 'NodeMap<bool> cut' is a member, in this way we can count it fast, after
18 the algorithm was run.
20 The constructor runs the algorithm.
24 T maxFlow() : returns the value of a maximum flow
26 T flowOnEdge(EdgeIt e) : for a fixed maximum flow x it returns x(e)
28 FlowMap Flow() : returns the fixed maximum flow x
30 void Flow(FlowMap& _flow ) : returns the fixed maximum flow x
32 void minMinCut(CutMap& M) : sets M to the characteristic vector of the
33 minimum min cut. M should be a map of bools initialized to false.
35 void maxMinCut(CutMap& M) : sets M to the characteristic vector of the
36 maximum min cut. M should be a map of bools initialized to false.
38 void minCut(CutMap& M) : fast function, sets M to the characteristic
39 vector of a minimum cut.
41 Different member from the other preflow_hl-s (here we have a member
44 CutMap minCut() : fast function, giving the characteristic
45 vector of a minimum cut.
58 #include <time_measure.h> //for test
62 template <typename Graph, typename T,
63 typename FlowMap=typename Graph::EdgeMap<T>,
64 typename CutMap=typename Graph::NodeMap<bool>,
65 typename CapMap=typename Graph::EdgeMap<T> >
68 typedef typename Graph::NodeIt NodeIt;
69 typedef typename Graph::EdgeIt EdgeIt;
70 typedef typename Graph::EachNodeIt EachNodeIt;
71 typedef typename Graph::OutEdgeIt OutEdgeIt;
72 typedef typename Graph::InEdgeIt InEdgeIt;
86 preflow_hl4(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) :
87 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity),
90 bool phase=0; //phase 0 is the 1st phase, phase 1 is the 2nd
97 b is a bound on the highest level of the stack.
98 k is a bound on the highest nonempty level i < n.
101 typename Graph::NodeMap<int> level(G,n);
102 typename Graph::NodeMap<T> excess(G);
104 std::vector<NodeIt> active(n);
105 typename Graph::NodeMap<NodeIt> next(G);
106 //Stack of the active nodes in level i < n.
107 //We use it in both phases.
109 typename Graph::NodeMap<NodeIt> left(G);
110 typename Graph::NodeMap<NodeIt> right(G);
111 std::vector<NodeIt> level_list(n);
113 Needed for the list of the nodes in level i.
116 /*Reverse_bfs from t, to find the starting level.*/
118 std::queue<NodeIt> bfs_queue;
121 while (!bfs_queue.empty()) {
123 NodeIt v=bfs_queue.front();
125 int l=level.get(v)+1;
127 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
129 if ( level.get(w) == n && w !=s ) {
131 NodeIt first=level_list[l];
132 if ( first != 0 ) left.set(first,w);
143 /* Starting flow. It is everywhere 0 at the moment. */
144 for(OutEdgeIt e=G.template first<OutEdgeIt>(s); e.valid(); ++e)
147 if ( c == 0 ) continue;
149 if ( level.get(w) < n ) {
150 if ( excess.get(w) == 0 && w!=t ) {
151 next.set(w,active[level.get(w)]);
152 active[level.get(w)]=w;
155 excess.set(w, excess.get(w)+c);
164 Push/relabel on the highest level active nodes.
172 In the end of phase 0 we apply a bfs from s in
177 //Now have a min cut.
178 for( EachNodeIt v=G.template first<EachNodeIt>();
180 if (level.get(v) >= n ) cut.set(v,true);
184 std::queue<NodeIt> bfs_queue;
187 while (!bfs_queue.empty()) {
189 NodeIt v=bfs_queue.front();
191 int l=level.get(v)+1;
193 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
194 if ( capacity.get(e) == flow.get(e) ) continue;
196 if ( level.get(u) >= n ) {
199 if ( excess.get(u) > 0 ) {
200 next.set(u,active[l]);
206 for(OutEdgeIt e=G.template first<OutEdgeIt>(v); e.valid(); ++e) {
207 if ( 0 == flow.get(e) ) continue;
209 if ( level.get(u) >= n ) {
212 if ( excess.get(u) > 0 ) {
213 next.set(u,active[l]);
223 if ( active[b] == 0 ) --b;
227 active[b]=next.get(w);
228 int lev=level.get(w);
230 int newlevel=n; //bound on the next level of w.
232 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
234 if ( flow.get(e) == capacity.get(e) ) continue;
238 if( lev > level.get(v) ) {
239 /*Push is allowed now*/
241 if ( excess.get(v)==0 && v!=t && v!=s ) {
242 int lev_v=level.get(v);
243 next.set(v,active[lev_v]);
247 T cap=capacity.get(e);
251 if ( remcap >= exc ) {
252 /*A nonsaturating push.*/
254 flow.set(e, flo+exc);
255 excess.set(v, excess.get(v)+exc);
260 /*A saturating push.*/
263 excess.set(v, excess.get(v)+remcap);
266 } else if ( newlevel > level.get(v) ){
267 newlevel = level.get(v);
274 for( InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
276 if( flow.get(e) == 0 ) continue;
280 if( lev > level.get(v) ) {
281 /*Push is allowed now*/
283 if ( excess.get(v)==0 && v!=t && v!=s ) {
284 int lev_v=level.get(v);
285 next.set(v,active[lev_v]);
292 /*A nonsaturating push.*/
294 flow.set(e, flo-exc);
295 excess.set(v, excess.get(v)+exc);
299 /*A saturating push.*/
301 excess.set(v, excess.get(v)+flo);
305 } else if ( newlevel > level.get(v) ) {
306 newlevel = level.get(v);
310 } // if w still has excess after the out edge for cycle
319 //now 'lev' is the old level of w
322 level.set(w,++newlevel);
323 next.set(w,active[newlevel]);
328 NodeIt right_n=right.get(w);
329 NodeIt left_n=left.get(w);
331 if ( right_n != 0 ) {
333 right.set(left_n, right_n);
334 left.set(right_n, left_n);
336 level_list[lev]=right_n;
337 left.set(right_n, 0);
341 right.set(left_n, 0);
349 if ( level_list[lev]==0 ) {
351 for (int i=lev; i!=k ; ) {
352 NodeIt v=level_list[++i];
367 if ( newlevel == n ) {
371 level.set(w,++newlevel);
372 next.set(w,active[newlevel]);
375 if ( k < newlevel ) ++k;
376 NodeIt first=level_list[newlevel];
377 if ( first != 0 ) left.set(first,w);
380 level_list[newlevel]=w;
385 if ( relabel >= heur ) {
390 for ( int i=1; i!=n; ++i ) {
395 //bfs from t in the res graph to relevel the nodes
396 for( EachNodeIt v=G.template first<EachNodeIt>();
397 v.valid(); ++v) level.set(v,n);
400 std::queue<NodeIt> bfs_queue;
403 while (!bfs_queue.empty()) {
405 NodeIt v=bfs_queue.front();
407 int l=level.get(v)+1;
409 for(InEdgeIt e=G.template first<InEdgeIt>(v);
411 if ( capacity.get(e) == flow.get(e) ) continue;
413 if ( level.get(u) == n ) {
416 if ( excess.get(u) > 0 ) {
417 next.set(u,active[l]);
420 NodeIt first=level_list[l];
421 if ( first != 0 ) left.set(first,w);
429 for(OutEdgeIt e=G.template first<OutEdgeIt>(v);
431 if ( 0 == flow.get(e) ) continue;
433 if ( level.get(u) == n ) {
436 if ( excess.get(u) > 0 ) {
437 next.set(u,active[l]);
440 NodeIt first=level_list[l];
441 if ( first != 0 ) left.set(first,w);
456 } // if stack[b] is nonempty
461 value = excess.get(t);
472 Returns the maximum value of a flow.
482 For the maximum flow x found by the algorithm, it returns the flow value on Edge e, i.e. x(e).
485 T flowOnEdge(EdgeIt e) {
497 void Flow(FlowMap& _flow ) {
498 for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v)
499 _flow.set(v,flow.get(v));
505 Returns the minimum min cut, by a bfs from s in the residual graph.
508 template<typename _CutMap>
509 void minMinCut(_CutMap& M) {
511 std::queue<NodeIt> queue;
516 while (!queue.empty()) {
517 NodeIt w=queue.front();
520 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
522 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
528 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
530 if (!M.get(v) && flow.get(e) > 0 ) {
543 Returns the maximum min cut, by a reverse bfs
544 from t in the residual graph.
547 template<typename _CutMap>
548 void maxMinCut(_CutMap& M) {
550 std::queue<NodeIt> queue;
555 while (!queue.empty()) {
556 NodeIt w=queue.front();
559 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
561 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
567 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
569 if (!M.get(v) && flow.get(e) > 0 ) {
576 for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v) {
583 template<typename _CutMap>
584 void minCut(_CutMap& M) {
585 for( EachNodeIt v=G.template first<EachNodeIt>();
587 M.set(v, cut.get(v));