Timer class for measuring user/system time added.
5 Runs the first phase of preflow.h
7 The constructor runs the algorithm.
11 T maxFlow() : returns the value of a maximum flow
13 CutMap minCut() : returns the characteristic vector of a min cut.
16 #ifndef PREFLOW_MAX_FLOW_H
17 #define PREFLOW_MAX_FLOW_H
27 template <typename Graph, typename T,
28 typename FlowMap=typename Graph::EdgeMap<T>,
29 typename CapMap=typename Graph::EdgeMap<T>,
30 typename CutMap=typename Graph::NodeMap<bool> >
31 class preflow_max_flow {
33 typedef typename Graph::NodeIt NodeIt;
34 typedef typename Graph::EdgeIt EdgeIt;
35 typedef typename Graph::EachNodeIt EachNodeIt;
36 typedef typename Graph::OutEdgeIt OutEdgeIt;
37 typedef typename Graph::InEdgeIt InEdgeIt;
49 preflow_max_flow(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity ) :
50 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity), cut(_G, false)
54 int heur0=(int)(H0*n); //time while running 'bound decrease'
55 int heur1=(int)(H1*n); //time while running 'highest label'
56 int heur=heur1; //starting time interval (#of relabels)
59 what_heur is 0 in case 'bound decrease'
60 and 1 in case 'highest label'
64 Needed for 'bound decrease', 'true'
65 means no active nodes are above bound b.
68 int k=n-2; //bound on the highest level under n containing a node
69 int b=k; //bound on the highest level under n of an active node
71 typename Graph::NodeMap<int> level(G,n);
72 typename Graph::NodeMap<T> excess(G);
74 std::vector<NodeIt> active(n);
75 typename Graph::NodeMap<NodeIt> next(G);
76 //Stack of the active nodes in level i < n.
77 //We use it in both phases.
79 typename Graph::NodeMap<NodeIt> left(G);
80 typename Graph::NodeMap<NodeIt> right(G);
81 std::vector<NodeIt> level_list(n);
83 List of the nodes in level i<n.
86 /*Reverse_bfs from t, to find the starting level.*/
88 std::queue<NodeIt> bfs_queue;
91 while (!bfs_queue.empty()) {
93 NodeIt v=bfs_queue.front();
97 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
99 if ( level.get(w) == n && w != s ) {
101 NodeIt first=level_list[l];
102 if ( first != 0 ) left.set(first,w);
113 /* Starting flow. It is everywhere 0 at the moment. */
114 for(OutEdgeIt e=G.template first<OutEdgeIt>(s); e.valid(); ++e)
117 if ( c == 0 ) continue;
119 if ( level.get(w) < n ) {
120 if ( excess.get(w) == 0 && w!=t ) {
121 next.set(w,active[level.get(w)]);
122 active[level.get(w)]=w;
125 excess.set(w, excess.get(w)+c);
136 Push/relabel on the highest level active nodes.
141 if ( !what_heur && !end && k > 0 ) {
148 if ( active[b] == 0 ) --b;
153 active[b]=next.get(w);
154 int lev=level.get(w);
156 int newlevel=n; //bound on the next level of w
158 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
160 if ( flow.get(e) == capacity.get(e) ) continue;
164 if( lev > level.get(v) ) {
165 /*Push is allowed now*/
167 if ( excess.get(v)==0 && v!=t && v!=s ) {
168 int lev_v=level.get(v);
169 next.set(v,active[lev_v]);
173 T cap=capacity.get(e);
177 if ( remcap >= exc ) {
178 /*A nonsaturating push.*/
180 flow.set(e, flo+exc);
181 excess.set(v, excess.get(v)+exc);
186 /*A saturating push.*/
189 excess.set(v, excess.get(v)+remcap);
192 } else if ( newlevel > level.get(v) ){
193 newlevel = level.get(v);
200 for( InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
202 if( flow.get(e) == 0 ) continue;
206 if( lev > level.get(v) ) {
207 /*Push is allowed now*/
209 if ( excess.get(v)==0 && v!=t && v!=s ) {
210 int lev_v=level.get(v);
211 next.set(v,active[lev_v]);
218 /*A nonsaturating push.*/
220 flow.set(e, flo-exc);
221 excess.set(v, excess.get(v)+exc);
225 /*A saturating push.*/
227 excess.set(v, excess.get(v)+flo);
231 } else if ( newlevel > level.get(v) ) {
232 newlevel = level.get(v);
236 } // if w still has excess after the out edge for cycle
246 //now 'lev' is the old level of w
249 NodeIt right_n=right.get(w);
250 NodeIt left_n=left.get(w);
252 if ( right_n != 0 ) {
254 right.set(left_n, right_n);
255 left.set(right_n, left_n);
257 level_list[lev]=right_n;
258 left.set(right_n, 0);
262 right.set(left_n, 0);
271 if ( level_list[lev]==0 ) {
273 for (int i=lev; i!=k ; ) {
274 NodeIt v=level_list[++i];
280 if ( !what_heur ) active[i]=0;
289 if ( newlevel == n ) level.set(w,n);
291 level.set(w,++newlevel);
292 next.set(w,active[newlevel]);
294 if ( what_heur ) b=newlevel;
295 if ( k < newlevel ) ++k;
296 NodeIt first=level_list[newlevel];
297 if ( first != 0 ) left.set(first,w);
300 level_list[newlevel]=w;
306 if ( relabel >= heur ) {
323 } // if stack[b] is nonempty
329 for( EachNodeIt v=G.template first<EachNodeIt>();
331 if (level.get(v) >= n ) cut.set(v,true);
333 value = excess.get(t);