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