Dynamic Maps added.
5 Runs the two phase highest label preflow push algorithm. In phase 0
6 we maintain in a list the nodes in level i < n, and we maintain a
7 bound k on the max level i < n containing a node, so we can do
8 the gap heuristic fast. Phase 1 is the same. (The algorithm is the
9 same as preflow.hl3, the only diff is that here we use the gap
10 heuristic with the list of the nodes on level i, and not a bfs form the
13 In phase 1 we shift everything downwards by n.
17 void run() : runs the algorithm
19 The following functions should be used after run() was already run.
21 T maxflow() : returns the value of a maximum flow
23 T flowonedge(EdgeIt e) : for a fixed maximum flow x it returns x(e)
25 FlowMap allflow() : returns a maximum flow
27 void allflow(FlowMap& _flow ) : returns a maximum flow
29 void mincut(CutMap& M) : sets M to the characteristic vector of a
30 minimum cut. M should be a map of bools initialized to false.
32 void min_mincut(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 max_mincut(CutMap& M) : sets M to the characteristic vector of the
36 maximum min cut. M should be a map of bools initialized to false.
49 template <typename Graph, typename T,
50 typename FlowMap=typename Graph::EdgeMap<T>,
51 typename CapMap=typename Graph::EdgeMap<T> >
54 typedef typename Graph::NodeIt NodeIt;
55 typedef typename Graph::EdgeIt EdgeIt;
56 typedef typename Graph::EachNodeIt EachNodeIt;
57 typedef typename Graph::OutEdgeIt OutEdgeIt;
58 typedef typename Graph::InEdgeIt InEdgeIt;
69 preflow_hl4(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) :
70 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity) { }
80 b is a bound on the highest level of the stack.
81 k is a bound on the highest nonempty level i < n.
84 typename Graph::NodeMap<int> level(G,n);
85 typename Graph::NodeMap<T> excess(G);
86 std::vector<std::stack<NodeIt> > stack(n);
87 //Stack of the active nodes in level i < n.
88 //We use it in both phases.
90 typename Graph::NodeMap<NodeIt> left(G);
91 typename Graph::NodeMap<NodeIt> right(G);
92 std::vector<NodeIt> level_list(n);
94 Needed for the list of the nodes in level i.
97 /*Reverse_bfs from t, to find the starting level.*/
99 std::queue<NodeIt> bfs_queue;
102 while (!bfs_queue.empty()) {
104 NodeIt v=bfs_queue.front();
106 int l=level.get(v)+1;
108 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
110 if ( level.get(w) == n ) {
112 NodeIt first=level_list[l];
113 if ( first != 0 ) left.set(first,w);
124 /* Starting flow. It is everywhere 0 at the moment. */
125 for(OutEdgeIt e=G.template first<OutEdgeIt>(s); e.valid(); ++e)
128 if ( c == 0 ) continue;
130 if ( level.get(w) < n ) {
131 if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w);
133 excess.set(w, excess.get(w)+c);
142 Push/relabel on the highest level active nodes.
150 In the end of phase 0 we apply a bfs from s in
155 std::queue<NodeIt> bfs_queue;
158 while (!bfs_queue.empty()) {
160 NodeIt v=bfs_queue.front();
162 int l=level.get(v)+1;
164 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
165 if ( capacity.get(e) == flow.get(e) ) continue;
167 if ( level.get(u) >= n ) {
170 if ( excess.get(u) > 0 ) stack[l].push(u);
174 for(OutEdgeIt e=G.template first<OutEdgeIt>(v); e.valid(); ++e) {
175 if ( 0 == flow.get(e) ) continue;
177 if ( level.get(u) >= n ) {
180 if ( excess.get(u) > 0 ) stack[l].push(u);
188 if ( stack[b].empty() ) --b;
191 NodeIt w=stack[b].top(); //w is a highest label active node.
193 int lev=level.get(w);
195 int newlevel=n; //In newlevel we bound the next level of w.
197 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
199 if ( flow.get(e) == capacity.get(e) ) continue;
203 if( lev > level.get(v) ) {
204 /*Push is allowed now*/
206 if ( excess.get(v)==0 && v!=t && v!=s )
207 stack[level.get(v)].push(v);
208 /*v becomes active.*/
210 T cap=capacity.get(e);
214 if ( remcap >= exc ) {
215 /*A nonsaturating push.*/
217 flow.set(e, flo+exc);
218 excess.set(v, excess.get(v)+exc);
223 /*A saturating push.*/
226 excess.set(v, excess.get(v)+remcap);
229 } else if ( newlevel > level.get(v) ){
230 newlevel = level.get(v);
237 for( InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
239 if( flow.get(e) == 0 ) continue;
243 if( lev > level.get(v) ) {
244 /*Push is allowed now*/
246 if ( excess.get(v)==0 && v!=t && v!=s )
247 stack[level.get(v)].push(v);
248 /*v becomes active.*/
253 /*A nonsaturating push.*/
255 flow.set(e, flo-exc);
256 excess.set(v, excess.get(v)+exc);
260 /*A saturating push.*/
262 excess.set(v, excess.get(v)+flo);
266 } else if ( newlevel > level.get(v) ) {
267 newlevel = level.get(v);
271 } // if w still has excess after the out edge for cycle
280 //now 'lev' is the old level of w
283 level.set(w,++newlevel);
284 stack[newlevel].push(w);
288 NodeIt right_n=right.get(w);
289 NodeIt left_n=left.get(w);
291 if ( right_n != 0 ) {
293 right.set(left_n, right_n);
294 left.set(right_n, left_n);
296 level_list[lev]=right_n;
297 left.set(right_n, 0);
301 right.set(left_n, 0);
308 if ( level_list[lev]==0 ) {
310 for (int i=lev; i!=k ; ) {
311 NodeIt v=level_list[++i];
326 if ( newlevel == n ) {
330 level.set(w,++newlevel);
331 stack[newlevel].push(w);
333 if ( k < newlevel ) ++k;
334 NodeIt first=level_list[newlevel];
335 if ( first != 0 ) left.set(first,w);
338 level_list[newlevel]=w;
345 } // if stack[b] is nonempty
350 value = excess.get(t);
361 Returns the maximum value of a flow.
371 For the maximum flow x found by the algorithm, it returns the flow value on Edge e, i.e. x(e).
374 T flowonedge(EdgeIt e) {
386 void allflow(FlowMap& _flow ) {
387 for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v)
388 _flow.set(v,flow.get(v));
394 Returns the minimum min cut, by a bfs from s in the residual graph.
397 template<typename CutMap>
398 void mincut(CutMap& M) {
400 std::queue<NodeIt> queue;
405 while (!queue.empty()) {
406 NodeIt w=queue.front();
409 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
411 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
417 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
419 if (!M.get(v) && flow.get(e) > 0 ) {
432 Returns the maximum min cut, by a reverse bfs
433 from t in the residual graph.
436 template<typename CutMap>
437 void max_mincut(CutMap& M) {
439 std::queue<NodeIt> queue;
444 while (!queue.empty()) {
445 NodeIt w=queue.front();
448 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
450 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
456 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
458 if (!M.get(v) && flow.get(e) > 0 ) {
465 for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v) {
473 template<typename CutMap>
474 void min_mincut(CutMap& M) {