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