src/work/jacint/preflow_excess.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000 (2004-09-08)
changeset 822 88226d9fe821
child 921 818510fa3d99
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

Some macros and comments has been changed.
jacint@437
     1
// -*- C++ -*-
jacint@437
     2
jacint@437
     3
//run gyorsan tudna adni a minmincutot a 2 fazis elejen , ne vegyuk be konstruktorba egy cutmapet?
jacint@437
     4
//constzero jo igy?
jacint@437
     5
jacint@437
     6
//majd marci megmondja betegyem-e bfs-t meg resgraphot
jacint@437
     7
jacint@437
     8
//constzero helyett az kell hogy flow-e vagy csak preflow, ha flow akor csak
jacint@437
     9
//excess[t]-t kell szmaolni
jacint@437
    10
jacint@437
    11
/*
jacint@437
    12
Heuristics: 
jacint@437
    13
 2 phase
jacint@437
    14
 gap
jacint@437
    15
 list 'level_list' on the nodes on level i implemented by hand
jacint@437
    16
 stack 'active' on the active nodes on level i implemented by hand
jacint@437
    17
 runs heuristic 'highest label' for H1*n relabels
jacint@437
    18
 runs heuristic 'bound decrease' for H0*n relabels, starts with 'highest label'
jacint@437
    19
 
jacint@437
    20
Parameters H0 and H1 are initialized to 20 and 10.
jacint@437
    21
jacint@437
    22
Constructors:
jacint@437
    23
jacint@437
    24
Preflow(Graph, Node, Node, CapMap, FlowMap, bool) : bool must be false if 
jacint@437
    25
     FlowMap is not constant zero, and should be true if it is
jacint@437
    26
jacint@437
    27
Members:
jacint@437
    28
jacint@437
    29
void run()
jacint@437
    30
jacint@437
    31
T flowValue() : returns the value of a maximum flow
jacint@437
    32
jacint@437
    33
void minMinCut(CutMap& M) : sets M to the characteristic vector of the 
jacint@437
    34
     minimum min cut. M should be a map of bools initialized to false.
jacint@437
    35
jacint@437
    36
void maxMinCut(CutMap& M) : sets M to the characteristic vector of the 
jacint@437
    37
     maximum min cut. M should be a map of bools initialized to false.
jacint@437
    38
jacint@437
    39
void minCut(CutMap& M) : sets M to the characteristic vector of 
jacint@437
    40
     a min cut. M should be a map of bools initialized to false.
jacint@437
    41
jacint@437
    42
FIXME reset
jacint@437
    43
jacint@437
    44
*/
jacint@437
    45
jacint@437
    46
#ifndef HUGO_PREFLOW_H
jacint@437
    47
#define HUGO_PREFLOW_H
jacint@437
    48
jacint@437
    49
#define H0 20
jacint@437
    50
#define H1 1
jacint@437
    51
jacint@437
    52
#include <vector>
jacint@437
    53
#include <queue>
jacint@437
    54
#include <stack>
jacint@437
    55
jacint@437
    56
namespace hugo {
jacint@437
    57
jacint@437
    58
  template <typename Graph, typename T, 
jacint@437
    59
	    typename CapMap=typename Graph::template EdgeMap<T>, 
jacint@437
    60
            typename FlowMap=typename Graph::template EdgeMap<T> >
jacint@437
    61
  class Preflow {
jacint@437
    62
    
jacint@437
    63
    typedef typename Graph::Node Node;
jacint@437
    64
    typedef typename Graph::Edge Edge;
jacint@437
    65
    typedef typename Graph::NodeIt NodeIt;
jacint@437
    66
    typedef typename Graph::OutEdgeIt OutEdgeIt;
jacint@437
    67
    typedef typename Graph::InEdgeIt InEdgeIt;
jacint@437
    68
    
jacint@437
    69
    const Graph& G;
jacint@437
    70
    Node s;
jacint@437
    71
    Node t;
jacint@437
    72
    const CapMap& capacity;  
jacint@437
    73
    FlowMap& flow;
jacint@437
    74
    T value;
jacint@437
    75
    bool constzero;
jacint@437
    76
    bool isflow;
jacint@437
    77
jacint@437
    78
  public:
jacint@437
    79
    Preflow(Graph& _G, Node _s, Node _t, CapMap& _capacity, 
jacint@437
    80
	    FlowMap& _flow, bool _constzero, bool _isflow ) :
jacint@437
    81
      G(_G), s(_s), t(_t), capacity(_capacity), flow(_flow), constzero(_constzero), isflow(_isflow) {}
jacint@437
    82
    
jacint@437
    83
    
jacint@437
    84
    void run() {
jacint@437
    85
      
jacint@437
    86
      value=0;                //for the subsequent runs
jacint@437
    87
jacint@437
    88
      bool phase=0;        //phase 0 is the 1st phase, phase 1 is the 2nd
jacint@437
    89
      int n=G.nodeNum(); 
jacint@437
    90
      int heur0=(int)(H0*n);  //time while running 'bound decrease' 
jacint@437
    91
      int heur1=(int)(H1*n);  //time while running 'highest label'
jacint@437
    92
      int heur=heur1;         //starting time interval (#of relabels)
jacint@437
    93
      bool what_heur=1;       
jacint@437
    94
      /*
jacint@437
    95
	what_heur is 0 in case 'bound decrease' 
jacint@437
    96
	and 1 in case 'highest label'
jacint@437
    97
      */
jacint@437
    98
      bool end=false;     
jacint@437
    99
      /*
jacint@437
   100
	Needed for 'bound decrease', 'true'
jacint@437
   101
	means no active nodes are above bound b.
jacint@437
   102
      */
jacint@437
   103
      int relabel=0;
jacint@437
   104
      int k=n-2;  //bound on the highest level under n containing a node
jacint@437
   105
      int b=k;    //bound on the highest level under n of an active node
jacint@437
   106
      
jacint@437
   107
      typename Graph::template NodeMap<int> level(G,n);      
jacint@437
   108
      typename Graph::template NodeMap<T> excess(G); 
jacint@437
   109
jacint@437
   110
      std::vector<std::stack<Node> > active(n);
jacint@437
   111
      /*      std::vector<Node> active(n-1,INVALID);
jacint@437
   112
      typename Graph::template NodeMap<Node> next(G,INVALID);
jacint@437
   113
      //Stack of the active nodes in level i < n.
jacint@437
   114
      //We use it in both phases.*/
jacint@437
   115
jacint@437
   116
      typename Graph::template NodeMap<Node> left(G,INVALID);
jacint@437
   117
      typename Graph::template NodeMap<Node> right(G,INVALID);
jacint@437
   118
      std::vector<Node> level_list(n,INVALID);
jacint@437
   119
      /*
jacint@437
   120
	List of the nodes in level i<n.
jacint@437
   121
      */
jacint@437
   122
jacint@437
   123
jacint@437
   124
      if ( constzero ) {
jacint@437
   125
     
jacint@437
   126
	/*Reverse_bfs from t, to find the starting level.*/
jacint@437
   127
	level.set(t,0);
jacint@437
   128
	std::queue<Node> bfs_queue;
jacint@437
   129
	bfs_queue.push(t);
jacint@437
   130
	
jacint@437
   131
	while (!bfs_queue.empty()) {
jacint@437
   132
	  
jacint@437
   133
	  Node v=bfs_queue.front();	
jacint@437
   134
	  bfs_queue.pop();
jacint@437
   135
	  int l=level[v]+1;
jacint@437
   136
	  
jacint@437
   137
	  InEdgeIt e;
jacint@437
   138
	  for(G.first(e,v); G.valid(e); G.next(e)) {
jacint@437
   139
	    Node w=G.tail(e);
jacint@437
   140
	    if ( level[w] == n && w != s ) {
jacint@437
   141
	      bfs_queue.push(w);
jacint@437
   142
	      Node first=level_list[l];
jacint@437
   143
	      if ( G.valid(first) ) left.set(first,w);
jacint@437
   144
	      right.set(w,first);
jacint@437
   145
	      level_list[l]=w;
jacint@437
   146
	      level.set(w, l);
jacint@437
   147
	    }
jacint@437
   148
	  }
jacint@437
   149
	}
jacint@437
   150
jacint@437
   151
	//the starting flow
jacint@437
   152
	OutEdgeIt e;
jacint@437
   153
	for(G.first(e,s); G.valid(e); G.next(e)) 
jacint@437
   154
	{
jacint@437
   155
	  T c=capacity[e];
jacint@437
   156
	  if ( c == 0 ) continue;
jacint@437
   157
	  Node w=G.head(e);
jacint@437
   158
	  if ( level[w] < n ) {	  
jacint@437
   159
	    if ( excess[w] == 0 && w!=t ) active[level[w]].push(w);
jacint@437
   160
	    flow.set(e, c); 
jacint@437
   161
	    excess.set(w, excess[w]+c);
jacint@437
   162
	  }
jacint@437
   163
	}
jacint@437
   164
      }
jacint@437
   165
      else 
jacint@437
   166
      {
jacint@437
   167
	
jacint@437
   168
	/*
jacint@437
   169
	  Reverse_bfs from t in the residual graph, 
jacint@437
   170
	  to find the starting level.
jacint@437
   171
	*/
jacint@437
   172
	level.set(t,0);
jacint@437
   173
	std::queue<Node> bfs_queue;
jacint@437
   174
	bfs_queue.push(t);
jacint@437
   175
	
jacint@437
   176
	while (!bfs_queue.empty()) {
jacint@437
   177
	  
jacint@437
   178
	  Node v=bfs_queue.front();	
jacint@437
   179
	  bfs_queue.pop();
jacint@437
   180
	  int l=level[v]+1;
jacint@437
   181
	  
jacint@437
   182
	  InEdgeIt e;
jacint@437
   183
	  for(G.first(e,v); G.valid(e); G.next(e)) {
jacint@437
   184
	    if ( capacity[e] == flow[e] ) continue;
jacint@437
   185
	    Node w=G.tail(e);
jacint@437
   186
	    if ( level[w] == n && w != s ) {
jacint@437
   187
	      bfs_queue.push(w);
jacint@437
   188
	      Node first=level_list[l];
jacint@437
   189
	      if ( G.valid(first) ) left.set(first,w);
jacint@437
   190
	      right.set(w,first);
jacint@437
   191
	      level_list[l]=w;
jacint@437
   192
	      level.set(w, l);
jacint@437
   193
	    }
jacint@437
   194
	  }
jacint@437
   195
	    
jacint@437
   196
	  OutEdgeIt f;
jacint@437
   197
	  for(G.first(f,v); G.valid(f); G.next(f)) {
jacint@437
   198
	    if ( 0 == flow[f] ) continue;
jacint@437
   199
	    Node w=G.head(f);
jacint@437
   200
	    if ( level[w] == n && w != s ) {
jacint@437
   201
	      bfs_queue.push(w);
jacint@437
   202
	      Node first=level_list[l];
jacint@437
   203
	      if ( G.valid(first) ) left.set(first,w);
jacint@437
   204
	      right.set(w,first);
jacint@437
   205
	      level_list[l]=w;
jacint@437
   206
	      level.set(w, l);
jacint@437
   207
	    }
jacint@437
   208
	  }
jacint@437
   209
	}
jacint@437
   210
      
jacint@437
   211
	
jacint@437
   212
	/*
jacint@437
   213
	  Counting the excess
jacint@437
   214
	*/
jacint@437
   215
jacint@437
   216
	if ( !isflow ) {
jacint@437
   217
	  NodeIt v;
jacint@437
   218
	  for(G.first(v); G.valid(v); G.next(v)) {
jacint@437
   219
	    T exc=0;
jacint@437
   220
	    
jacint@437
   221
	    InEdgeIt e;
jacint@437
   222
	    for(G.first(e,v); G.valid(e); G.next(e)) exc+=flow[e];
jacint@437
   223
	    OutEdgeIt f;
jacint@437
   224
	    for(G.first(f,v); G.valid(f); G.next(f)) exc-=flow[f];
jacint@437
   225
	    
jacint@437
   226
	    excess.set(v,exc);	  
jacint@437
   227
	    
jacint@437
   228
	    //putting the active nodes into the stack
jacint@437
   229
	    int lev=level[v];
jacint@437
   230
	    if ( exc > 0 && lev < n && v != t ) active[lev].push(v);
jacint@437
   231
	  }
jacint@437
   232
	} else {
jacint@437
   233
	  T exc=0;
jacint@437
   234
	    
jacint@437
   235
	  InEdgeIt e;
jacint@437
   236
	  for(G.first(e,t); G.valid(e); G.next(e)) exc+=flow[e];
jacint@437
   237
	  OutEdgeIt f;
jacint@437
   238
	  for(G.first(f,t); G.valid(f); G.next(f)) exc-=flow[f];
jacint@437
   239
jacint@437
   240
	  excess.set(t,exc);	  
jacint@437
   241
	}
jacint@437
   242
jacint@437
   243
jacint@437
   244
	//the starting flow
jacint@437
   245
	OutEdgeIt e;
jacint@437
   246
	for(G.first(e,s); G.valid(e); G.next(e)) 
jacint@437
   247
	{
jacint@437
   248
	  T rem=capacity[e]-flow[e];
jacint@437
   249
	  if ( rem == 0 ) continue;
jacint@437
   250
	  Node w=G.head(e);
jacint@437
   251
	  if ( level[w] < n ) {	  
jacint@437
   252
	    if ( excess[w] == 0 && w!=t ) active[level[w]].push(w);
jacint@437
   253
	    flow.set(e, capacity[e]); 
jacint@437
   254
	    excess.set(w, excess[w]+rem);
jacint@437
   255
	  }
jacint@437
   256
	}
jacint@437
   257
	
jacint@437
   258
	InEdgeIt f;
jacint@437
   259
	for(G.first(f,s); G.valid(f); G.next(f)) 
jacint@437
   260
	{
jacint@437
   261
	  if ( flow[f] == 0 ) continue;
jacint@437
   262
	  Node w=G.tail(f);
jacint@437
   263
	  if ( level[w] < n ) {	  
jacint@437
   264
	    if ( excess[w] == 0 && w!=t ) active[level[w]].push(w);
jacint@437
   265
	    excess.set(w, excess[w]+flow[f]);
jacint@437
   266
	    flow.set(f, 0); 
jacint@437
   267
	  }
jacint@437
   268
	}
jacint@437
   269
      }
jacint@437
   270
jacint@437
   271
jacint@437
   272
jacint@437
   273
jacint@437
   274
      /* 
jacint@437
   275
	 End of preprocessing 
jacint@437
   276
      */
jacint@437
   277
jacint@437
   278
jacint@437
   279
jacint@437
   280
      /*
jacint@437
   281
	Push/relabel on the highest level active nodes.
jacint@437
   282
      */	
jacint@437
   283
      while ( true ) {
jacint@437
   284
	
jacint@437
   285
	if ( b == 0 ) {
jacint@437
   286
	  if ( phase ) break;
jacint@437
   287
	  
jacint@437
   288
	  if ( !what_heur && !end && k > 0 ) {
jacint@437
   289
	    b=k;
jacint@437
   290
	    end=true;
jacint@437
   291
	  } else {
jacint@437
   292
	    phase=1;
jacint@437
   293
	    level.set(s,0);
jacint@437
   294
	    std::queue<Node> bfs_queue;
jacint@437
   295
	    bfs_queue.push(s);
jacint@437
   296
	    
jacint@437
   297
	    while (!bfs_queue.empty()) {
jacint@437
   298
	      
jacint@437
   299
	      Node v=bfs_queue.front();	
jacint@437
   300
	      bfs_queue.pop();
jacint@437
   301
	      int l=level[v]+1;
jacint@437
   302
	      
jacint@437
   303
	      InEdgeIt e;
jacint@437
   304
	      for(G.first(e,v); G.valid(e); G.next(e)) {
jacint@437
   305
		if ( capacity[e] == flow[e] ) continue;
jacint@437
   306
		Node u=G.tail(e);
jacint@437
   307
		if ( level[u] >= n ) { 
jacint@437
   308
		  bfs_queue.push(u);
jacint@437
   309
		  level.set(u, l);
jacint@437
   310
		  if ( excess[u] > 0 ) active[l].push(u);
jacint@437
   311
		}
jacint@437
   312
	      }
jacint@437
   313
	    
jacint@437
   314
	      OutEdgeIt f;
jacint@437
   315
	      for(G.first(f,v); G.valid(f); G.next(f)) {
jacint@437
   316
		if ( 0 == flow[f] ) continue;
jacint@437
   317
		Node u=G.head(f);
jacint@437
   318
		if ( level[u] >= n ) { 
jacint@437
   319
		  bfs_queue.push(u);
jacint@437
   320
		  level.set(u, l);
jacint@437
   321
		  if ( excess[u] > 0 ) active[l].push(u);
jacint@437
   322
		}
jacint@437
   323
	      }
jacint@437
   324
	    }
jacint@437
   325
	    b=n-2;
jacint@437
   326
	    }
jacint@437
   327
	    
jacint@437
   328
	}
jacint@437
   329
	  
jacint@437
   330
jacint@437
   331
	///	  
jacint@437
   332
	if ( active[b].empty() ) --b; 
jacint@437
   333
	else {
jacint@437
   334
	  end=false;  
jacint@437
   335
jacint@437
   336
	  Node w=active[b].top();
jacint@437
   337
	  active[b].pop();
jacint@437
   338
	  int lev=level[w];
jacint@437
   339
	  T exc=excess[w];
jacint@437
   340
	  int newlevel=n;       //bound on the next level of w
jacint@437
   341
	  
jacint@437
   342
	  OutEdgeIt e;
jacint@437
   343
	  for(G.first(e,w); G.valid(e); G.next(e)) {
jacint@437
   344
	    
jacint@437
   345
	    if ( flow[e] == capacity[e] ) continue; 
jacint@437
   346
	    Node v=G.head(e);            
jacint@437
   347
	    //e=wv	    
jacint@437
   348
	    
jacint@437
   349
	    if( lev > level[v] ) {      
jacint@437
   350
	      /*Push is allowed now*/
jacint@437
   351
	      
jacint@437
   352
	      if ( excess[v]==0 && v!=t && v!=s ) {
jacint@437
   353
		int lev_v=level[v];
jacint@437
   354
		active[lev_v].push(v);
jacint@437
   355
	      }
jacint@437
   356
	      
jacint@437
   357
	      T cap=capacity[e];
jacint@437
   358
	      T flo=flow[e];
jacint@437
   359
	      T remcap=cap-flo;
jacint@437
   360
	      
jacint@437
   361
	      if ( remcap >= exc ) {       
jacint@437
   362
		/*A nonsaturating push.*/
jacint@437
   363
		
jacint@437
   364
		flow.set(e, flo+exc);
jacint@437
   365
		excess.set(v, excess[v]+exc);
jacint@437
   366
		exc=0;
jacint@437
   367
		break; 
jacint@437
   368
		
jacint@437
   369
	      } else { 
jacint@437
   370
		/*A saturating push.*/
jacint@437
   371
		
jacint@437
   372
		flow.set(e, cap);
jacint@437
   373
		excess.set(v, excess[v]+remcap);
jacint@437
   374
		exc-=remcap;
jacint@437
   375
	      }
jacint@437
   376
	    } else if ( newlevel > level[v] ){
jacint@437
   377
	      newlevel = level[v];
jacint@437
   378
	    }	    
jacint@437
   379
	    
jacint@437
   380
	  } //for out edges wv 
jacint@437
   381
	
jacint@437
   382
	
jacint@437
   383
	if ( exc > 0 ) {	
jacint@437
   384
	  InEdgeIt e;
jacint@437
   385
	  for(G.first(e,w); G.valid(e); G.next(e)) {
jacint@437
   386
	    
jacint@437
   387
	    if( flow[e] == 0 ) continue; 
jacint@437
   388
	    Node v=G.tail(e);  
jacint@437
   389
	    //e=vw
jacint@437
   390
	    
jacint@437
   391
	    if( lev > level[v] ) {  
jacint@437
   392
	      /*Push is allowed now*/
jacint@437
   393
	      
jacint@437
   394
	      if ( excess[v]==0 && v!=t && v!=s ) {
jacint@437
   395
		int lev_v=level[v];
jacint@437
   396
		active[lev_v].push(v);
jacint@437
   397
	      }
jacint@437
   398
	      
jacint@437
   399
	      T flo=flow[e];
jacint@437
   400
	      
jacint@437
   401
	      if ( flo >= exc ) { 
jacint@437
   402
		/*A nonsaturating push.*/
jacint@437
   403
		
jacint@437
   404
		flow.set(e, flo-exc);
jacint@437
   405
		excess.set(v, excess[v]+exc);
jacint@437
   406
		exc=0;
jacint@437
   407
		break; 
jacint@437
   408
	      } else {                                               
jacint@437
   409
		/*A saturating push.*/
jacint@437
   410
		
jacint@437
   411
		excess.set(v, excess[v]+flo);
jacint@437
   412
		exc-=flo;
jacint@437
   413
		flow.set(e,0);
jacint@437
   414
	      }  
jacint@437
   415
	    } else if ( newlevel > level[v] ) {
jacint@437
   416
	      newlevel = level[v];
jacint@437
   417
	    }	    
jacint@437
   418
	  } //for in edges vw
jacint@437
   419
	  
jacint@437
   420
	} // if w still has excess after the out edge for cycle
jacint@437
   421
	
jacint@437
   422
	excess.set(w, exc);
jacint@437
   423
	///	push
jacint@437
   424
jacint@437
   425
 
jacint@437
   426
	/*
jacint@437
   427
	  Relabel
jacint@437
   428
	*/
jacint@437
   429
	
jacint@437
   430
jacint@437
   431
	if ( exc > 0 ) {
jacint@437
   432
	  //now 'lev' is the old level of w
jacint@437
   433
	
jacint@437
   434
	  if ( phase ) {
jacint@437
   435
	    level.set(w,++newlevel);
jacint@437
   436
	    active[newlevel].push(w);
jacint@437
   437
	    b=newlevel;
jacint@437
   438
	  } else {
jacint@437
   439
	    //unlacing starts
jacint@437
   440
	    Node right_n=right[w];
jacint@437
   441
	    Node left_n=left[w];
jacint@437
   442
jacint@437
   443
	    if ( G.valid(right_n) ) {
jacint@437
   444
	      if ( G.valid(left_n) ) {
jacint@437
   445
		right.set(left_n, right_n);
jacint@437
   446
		left.set(right_n, left_n);
jacint@437
   447
	      } else {
jacint@437
   448
		level_list[lev]=right_n;   
jacint@437
   449
		left.set(right_n, INVALID);
jacint@437
   450
	      } 
jacint@437
   451
	    } else {
jacint@437
   452
	      if ( G.valid(left_n) ) {
jacint@437
   453
		right.set(left_n, INVALID);
jacint@437
   454
	      } else { 
jacint@437
   455
		level_list[lev]=INVALID;   
jacint@437
   456
	      } 
jacint@437
   457
	    } 
jacint@437
   458
	    //unlacing ends
jacint@437
   459
		
jacint@437
   460
	    if ( !G.valid(level_list[lev]) ) {
jacint@437
   461
	      
jacint@437
   462
	       //gapping starts
jacint@437
   463
	      for (int i=lev; i!=k ; ) {
jacint@437
   464
		Node v=level_list[++i];
jacint@437
   465
		while ( G.valid(v) ) {
jacint@437
   466
		  level.set(v,n);
jacint@437
   467
		  v=right[v];
jacint@437
   468
		}
jacint@437
   469
		level_list[i]=INVALID;
jacint@437
   470
		if ( !what_heur ) {
jacint@437
   471
		  while ( !active[i].empty() ) {
jacint@437
   472
		    active[i].pop();    //FIXME: ezt szebben kene
jacint@437
   473
		  }
jacint@437
   474
		}	     
jacint@437
   475
	      }
jacint@437
   476
jacint@437
   477
	      level.set(w,n);
jacint@437
   478
	      b=lev-1;
jacint@437
   479
	      k=b;
jacint@437
   480
	      //gapping ends
jacint@437
   481
	    
jacint@437
   482
	    } else {
jacint@437
   483
	      
jacint@437
   484
	      if ( newlevel == n ) level.set(w,n); 
jacint@437
   485
	      else {
jacint@437
   486
		level.set(w,++newlevel);
jacint@437
   487
		active[newlevel].push(w);
jacint@437
   488
		if ( what_heur ) b=newlevel;
jacint@437
   489
		if ( k < newlevel ) ++k;      //now k=newlevel
jacint@437
   490
		Node first=level_list[newlevel];
jacint@437
   491
		if ( G.valid(first) ) left.set(first,w);
jacint@437
   492
		right.set(w,first);
jacint@437
   493
		left.set(w,INVALID);
jacint@437
   494
		level_list[newlevel]=w;
jacint@437
   495
	      }
jacint@437
   496
	    }
jacint@437
   497
jacint@437
   498
jacint@437
   499
	    ++relabel; 
jacint@437
   500
	    if ( relabel >= heur ) {
jacint@437
   501
	      relabel=0;
jacint@437
   502
	      if ( what_heur ) {
jacint@437
   503
		what_heur=0;
jacint@437
   504
		heur=heur0;
jacint@437
   505
		end=false;
jacint@437
   506
	      } else {
jacint@437
   507
		what_heur=1;
jacint@437
   508
		heur=heur1;
jacint@437
   509
		b=k; 
jacint@437
   510
	      }
jacint@437
   511
	    }
jacint@437
   512
	  } //phase 0
jacint@437
   513
	  
jacint@437
   514
	  
jacint@437
   515
	} // if ( exc > 0 )
jacint@437
   516
	  
jacint@437
   517
	
jacint@437
   518
	}  // if stack[b] is nonempty
jacint@437
   519
	
jacint@437
   520
      } // while(true)
jacint@437
   521
jacint@437
   522
jacint@437
   523
      value = excess[t];
jacint@437
   524
      /*Max flow value.*/
jacint@437
   525
     
jacint@437
   526
    } //void run()
jacint@437
   527
jacint@437
   528
jacint@437
   529
jacint@437
   530
jacint@437
   531
jacint@437
   532
    /*
jacint@437
   533
      Returns the maximum value of a flow.
jacint@437
   534
     */
jacint@437
   535
jacint@437
   536
    T flowValue() {
jacint@437
   537
      return value;
jacint@437
   538
    }
jacint@437
   539
jacint@437
   540
jacint@437
   541
    FlowMap Flow() {
jacint@437
   542
      return flow;
jacint@437
   543
      }
jacint@437
   544
jacint@437
   545
jacint@437
   546
    void Flow(FlowMap& _flow ) {
jacint@437
   547
      NodeIt v;
jacint@437
   548
      for(G.first(v) ; G.valid(v); G.next(v))
jacint@437
   549
	_flow.set(v,flow[v]);
jacint@437
   550
    }
jacint@437
   551
jacint@437
   552
jacint@437
   553
jacint@437
   554
    /*
jacint@437
   555
      Returns the minimum min cut, by a bfs from s in the residual graph.
jacint@437
   556
    */
jacint@437
   557
   
jacint@437
   558
    template<typename _CutMap>
jacint@437
   559
    void minMinCut(_CutMap& M) {
jacint@437
   560
    
jacint@437
   561
      std::queue<Node> queue;
jacint@437
   562
      
jacint@437
   563
      M.set(s,true);      
jacint@437
   564
      queue.push(s);
jacint@437
   565
jacint@437
   566
      while (!queue.empty()) {
jacint@437
   567
        Node w=queue.front();
jacint@437
   568
	queue.pop();
jacint@437
   569
jacint@437
   570
	OutEdgeIt e;
jacint@437
   571
	for(G.first(e,w) ; G.valid(e); G.next(e)) {
jacint@437
   572
	  Node v=G.head(e);
jacint@437
   573
	  if (!M[v] && flow[e] < capacity[e] ) {
jacint@437
   574
	    queue.push(v);
jacint@437
   575
	    M.set(v, true);
jacint@437
   576
	  }
jacint@437
   577
	} 
jacint@437
   578
jacint@437
   579
	InEdgeIt f;
jacint@437
   580
	for(G.first(f,w) ; G.valid(f); G.next(f)) {
jacint@437
   581
	  Node v=G.tail(f);
jacint@437
   582
	  if (!M[v] && flow[f] > 0 ) {
jacint@437
   583
	    queue.push(v);
jacint@437
   584
	    M.set(v, true);
jacint@437
   585
	  }
jacint@437
   586
	} 
jacint@437
   587
      }
jacint@437
   588
    }
jacint@437
   589
jacint@437
   590
jacint@437
   591
  
jacint@437
   592
    /*
jacint@437
   593
      Returns the maximum min cut, by a reverse bfs 
jacint@437
   594
      from t in the residual graph.
jacint@437
   595
    */
jacint@437
   596
    
jacint@437
   597
    template<typename _CutMap>
jacint@437
   598
    void maxMinCut(_CutMap& M) {
jacint@437
   599
    
jacint@437
   600
      std::queue<Node> queue;
jacint@437
   601
      
jacint@437
   602
      M.set(t,true);        
jacint@437
   603
      queue.push(t);
jacint@437
   604
jacint@437
   605
      while (!queue.empty()) {
jacint@437
   606
        Node w=queue.front();
jacint@437
   607
	queue.pop();
jacint@437
   608
jacint@437
   609
jacint@437
   610
	InEdgeIt e;
jacint@437
   611
	for(G.first(e,w) ; G.valid(e); G.next(e)) {
jacint@437
   612
	  Node v=G.tail(e);
jacint@437
   613
	  if (!M[v] && flow[e] < capacity[e] ) {
jacint@437
   614
	    queue.push(v);
jacint@437
   615
	    M.set(v, true);
jacint@437
   616
	  }
jacint@437
   617
	}
jacint@437
   618
	
jacint@437
   619
	OutEdgeIt f;
jacint@437
   620
	for(G.first(f,w) ; G.valid(f); G.next(f)) {
jacint@437
   621
	  Node v=G.head(f);
jacint@437
   622
	  if (!M[v] && flow[f] > 0 ) {
jacint@437
   623
	    queue.push(v);
jacint@437
   624
	    M.set(v, true);
jacint@437
   625
	  }
jacint@437
   626
	}
jacint@437
   627
      }
jacint@437
   628
jacint@437
   629
      NodeIt v;
jacint@437
   630
      for(G.first(v) ; G.valid(v); G.next(v)) {
jacint@437
   631
	M.set(v, !M[v]);
jacint@437
   632
      }
jacint@437
   633
jacint@437
   634
    }
jacint@437
   635
jacint@437
   636
jacint@437
   637
jacint@437
   638
    template<typename CutMap>
jacint@437
   639
    void minCut(CutMap& M) {
jacint@437
   640
      minMinCut(M);
jacint@437
   641
    }
jacint@437
   642
jacint@437
   643
    
jacint@437
   644
    void resetTarget (Node _t) {t=_t;}
jacint@437
   645
    void resetSource (Node _s) {s=_s;}
jacint@437
   646
   
jacint@437
   647
    void resetCap (CapMap _cap) {capacity=_cap;}
jacint@437
   648
jacint@437
   649
    void resetFlow (FlowMap _flow, bool _constzero) {
jacint@437
   650
      flow=_flow;
jacint@437
   651
      constzero=_constzero;
jacint@437
   652
    }
jacint@437
   653
jacint@437
   654
jacint@437
   655
jacint@437
   656
  };
jacint@437
   657
jacint@437
   658
} //namespace hugo
jacint@437
   659
jacint@437
   660
#endif //PREFLOW_H
jacint@437
   661
jacint@437
   662
jacint@437
   663
jacint@437
   664