src/work/jacint/preflow_excess.h
author klao
Fri, 04 Jun 2004 16:05:20 +0000
changeset 675 38755a4d4b51
child 921 818510fa3d99
permissions -rw-r--r--
My notes.
Sources of information and software packages which could be interesting wrt
HUGO.
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