Changeset 109:fc5982b39e10 in lemon-0.x for src/work/jacint/preflow_hl4.h
- Timestamp:
- 02/21/04 22:01:22 (20 years ago)
- Branch:
- default
- Phase:
- public
- Convert:
- svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@144
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/work/jacint/preflow_hl4.h
r105 r109 1 1 // -*- C++ -*- 2 2 /* 3 preflow_h l4.h3 preflow_h5.h 4 4 by jacint. 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 11 upgraded node.) 12 13 In phase 1 we shift everything downwards by n. 14 15 Member functions: 16 17 void run() : runs the algorithm 18 19 The following functions should be used after run() was already run. 20 21 T maxflow() : returns the value of a maximum flow 22 23 T flowonedge(EdgeIt e) : for a fixed maximum flow x it returns x(e) 24 25 FlowMap allflow() : returns a maximum flow 26 27 void allflow(FlowMap& _flow ) : returns a maximum flow 28 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. 31 32 void min _mincut(CutMap& M) : sets M to the characteristic vector of the5 Heuristics: 6 2 phase 7 gap 8 list 'level_list' on the nodes on level i implemented by hand 9 highest label 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 13 14 Due to the last heuristic, this algorithm is quite fast on very 15 sparse graphs, but relatively bad on even the dense graphs. 16 17 'NodeMap<bool> cut' is a member, in this way we can count it fast, after 18 the algorithm was run. 19 20 The constructor runs the algorithm. 21 22 Members: 23 24 T maxFlow() : returns the value of a maximum flow 25 26 T flowOnEdge(EdgeIt e) : for a fixed maximum flow x it returns x(e) 27 28 FlowMap Flow() : returns the fixed maximum flow x 29 30 void Flow(FlowMap& _flow ) : returns the fixed maximum flow x 31 32 void minMinCut(CutMap& M) : sets M to the characteristic vector of the 33 33 minimum min cut. M should be a map of bools initialized to false. 34 34 35 void max _mincut(CutMap& M) : sets M to the characteristic vector of the35 void maxMinCut(CutMap& M) : sets M to the characteristic vector of the 36 36 maximum min cut. M should be a map of bools initialized to false. 37 38 void minCut(CutMap& M) : fast function, sets M to the characteristic 39 vector of a minimum cut. 40 41 Different member from the other preflow_hl-s (here we have a member 42 'NodeMap<bool> cut'). 43 44 CutMap minCut() : fast function, giving the characteristic 45 vector of a minimum cut. 46 37 47 38 48 */ … … 41 51 #define PREFLOW_HL4_H 42 52 53 #define BFS 20 54 43 55 #include <vector> 44 #include <stack>45 56 #include <queue> 57 58 #include <time_measure.h> //for test 46 59 47 60 namespace hugo { … … 49 62 template <typename Graph, typename T, 50 63 typename FlowMap=typename Graph::EdgeMap<T>, 64 typename CutMap=typename Graph::NodeMap<bool>, 51 65 typename CapMap=typename Graph::EdgeMap<T> > 52 66 class preflow_hl4 { … … 63 77 FlowMap flow; 64 78 CapMap& capacity; 79 CutMap cut; 65 80 T value; 66 81 67 82 public: 68 83 84 double time; 85 69 86 preflow_hl4(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) : 70 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity) { } 71 72 73 void run() { 74 75 bool phase=0; 87 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity), 88 cut(G, false) { 89 90 bool phase=0; //phase 0 is the 1st phase, phase 1 is the 2nd 76 91 int n=G.nodeNum(); 92 int relabel=0; 93 int heur=(int)BFS*n; 77 94 int k=n-2; 78 95 int b=k; … … 84 101 typename Graph::NodeMap<int> level(G,n); 85 102 typename Graph::NodeMap<T> excess(G); 86 std::vector<std::stack<NodeIt> > stack(n); 103 104 std::vector<NodeIt> active(n); 105 typename Graph::NodeMap<NodeIt> next(G); 87 106 //Stack of the active nodes in level i < n. 88 107 //We use it in both phases. … … 108 127 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) { 109 128 NodeIt w=G.tail(e); 110 if ( level.get(w) == n ) {129 if ( level.get(w) == n && w !=s ) { 111 130 bfs_queue.push(w); 112 131 NodeIt first=level_list[l]; … … 129 148 NodeIt w=G.head(e); 130 149 if ( level.get(w) < n ) { 131 if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w); 150 if ( excess.get(w) == 0 && w!=t ) { 151 next.set(w,active[level.get(w)]); 152 active[level.get(w)]=w; 153 } 132 154 flow.set(e, c); 133 155 excess.set(w, excess.get(w)+c); … … 152 174 */ 153 175 phase=1; 176 177 //Now have a min cut. 178 for( EachNodeIt v=G.template first<EachNodeIt>(); 179 v.valid(); ++v) 180 if (level.get(v) >= n ) cut.set(v,true); 181 182 time=currTime(); 154 183 level.set(s,0); 155 184 std::queue<NodeIt> bfs_queue; … … 168 197 bfs_queue.push(u); 169 198 level.set(u, l); 170 if ( excess.get(u) > 0 ) stack[l].push(u); 199 if ( excess.get(u) > 0 ) { 200 next.set(u,active[l]); 201 active[l]=u; 202 } 171 203 } 172 204 } … … 178 210 bfs_queue.push(u); 179 211 level.set(u, l); 180 if ( excess.get(u) > 0 ) stack[l].push(u); 212 if ( excess.get(u) > 0 ) { 213 next.set(u,active[l]); 214 active[l]=u; 215 } 181 216 } 182 217 } … … 186 221 187 222 188 if ( stack[b].empty()) --b;223 if ( active[b] == 0 ) --b; 189 224 else { 190 225 191 NodeIt w= stack[b].top(); //w is a highest label active node.192 stack[b].pop();226 NodeIt w=active[b]; 227 active[b]=next.get(w); 193 228 int lev=level.get(w); 194 229 T exc=excess.get(w); 195 int newlevel=n; // In newlevel we boundthe next level of w.230 int newlevel=n; //bound on the next level of w. 196 231 197 232 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) { … … 204 239 /*Push is allowed now*/ 205 240 206 if ( excess.get(v)==0 && v!=t && v!=s ) 207 stack[level.get(v)].push(v); 208 /*v becomes active.*/ 241 if ( excess.get(v)==0 && v!=t && v!=s ) { 242 int lev_v=level.get(v); 243 next.set(v,active[lev_v]); 244 active[lev_v]=v; 245 } 209 246 210 247 T cap=capacity.get(e); … … 244 281 /*Push is allowed now*/ 245 282 246 if ( excess.get(v)==0 && v!=t && v!=s ) 247 stack[level.get(v)].push(v); 248 /*v becomes active.*/ 283 if ( excess.get(v)==0 && v!=t && v!=s ) { 284 int lev_v=level.get(v); 285 next.set(v,active[lev_v]); 286 active[lev_v]=v; 287 } 249 288 250 289 T flo=flow.get(e); … … 282 321 if ( phase ) { 283 322 level.set(w,++newlevel); 284 stack[newlevel].push(w); 323 next.set(w,active[newlevel]); 324 active[newlevel]=w; 285 325 b=newlevel; 286 326 } else { … … 304 344 } 305 345 } 346 //unlacing ends 306 347 307 348 … … 329 370 330 371 level.set(w,++newlevel); 331 stack[newlevel].push(w); 372 next.set(w,active[newlevel]); 373 active[newlevel]=w; 332 374 b=newlevel; 333 375 if ( k < newlevel ) ++k; … … 339 381 } 340 382 } 383 384 ++relabel; 385 if ( relabel >= heur ) { 386 relabel=0; 387 b=n-2; 388 k=b; 389 390 for ( int i=1; i!=n; ++i ) { 391 active[i]=0; 392 level_list[i]=0; 393 } 394 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); 398 399 level.set(t,0); 400 std::queue<NodeIt> bfs_queue; 401 bfs_queue.push(t); 402 403 while (!bfs_queue.empty()) { 404 405 NodeIt v=bfs_queue.front(); 406 bfs_queue.pop(); 407 int l=level.get(v)+1; 408 409 for(InEdgeIt e=G.template first<InEdgeIt>(v); 410 e.valid(); ++e) { 411 if ( capacity.get(e) == flow.get(e) ) continue; 412 NodeIt u=G.tail(e); 413 if ( level.get(u) == n ) { 414 bfs_queue.push(u); 415 level.set(u, l); 416 if ( excess.get(u) > 0 ) { 417 next.set(u,active[l]); 418 active[l]=u; 419 } 420 NodeIt first=level_list[l]; 421 if ( first != 0 ) left.set(first,w); 422 right.set(w,first); 423 left.set(w,0); 424 level_list[l]=w; 425 } 426 } 427 428 429 for(OutEdgeIt e=G.template first<OutEdgeIt>(v); 430 e.valid(); ++e) { 431 if ( 0 == flow.get(e) ) continue; 432 NodeIt u=G.head(e); 433 if ( level.get(u) == n ) { 434 bfs_queue.push(u); 435 level.set(u, l); 436 if ( excess.get(u) > 0 ) { 437 next.set(u,active[l]); 438 active[l]=u; 439 } 440 NodeIt first=level_list[l]; 441 if ( first != 0 ) left.set(first,w); 442 right.set(w,first); 443 left.set(w,0); 444 level_list[l]=w; 445 } 446 } 447 } 448 449 level.set(s,n); 450 } 451 341 452 } //phase 0 342 453 } // if ( exc > 0 ) 343 454 344 455 345 456 } // if stack[b] is nonempty … … 362 473 */ 363 474 364 T max flow() {475 T maxFlow() { 365 476 return value; 366 477 } … … 372 483 */ 373 484 374 T flow onedge(EdgeIt e) {485 T flowOnEdge(EdgeIt e) { 375 486 return flow.get(e); 376 487 } … … 378 489 379 490 380 FlowMap allflow() {491 FlowMap Flow() { 381 492 return flow; 382 493 } … … 384 495 385 496 386 void allflow(FlowMap& _flow ) {497 void Flow(FlowMap& _flow ) { 387 498 for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v) 388 499 _flow.set(v,flow.get(v)); … … 395 506 */ 396 507 397 template<typename CutMap>398 void min cut(CutMap& M) {508 template<typename _CutMap> 509 void minMinCut(_CutMap& M) { 399 510 400 511 std::queue<NodeIt> queue; … … 434 545 */ 435 546 436 template<typename CutMap>437 void max _mincut(CutMap& M) {547 template<typename _CutMap> 548 void maxMinCut(_CutMap& M) { 438 549 439 550 std::queue<NodeIt> queue; … … 470 581 471 582 472 473 template<typename CutMap> 474 void min_mincut(CutMap& M) { 475 mincut(M); 476 } 477 583 template<typename _CutMap> 584 void minCut(_CutMap& M) { 585 for( EachNodeIt v=G.template first<EachNodeIt>(); 586 v.valid(); ++v) 587 M.set(v, cut.get(v)); 588 } 589 590 591 CutMap minCut() { 592 return cut; 593 } 478 594 479 595 480 596 }; 481 }//namespace hugo597 }//namespace marci 482 598 #endif 483 599
Note: See TracChangeset
for help on using the changeset viewer.