src/work/athos/preflow_push.hh
author deba
Wed, 08 Sep 2004 12:06:45 +0000 (2004-09-08)
changeset 822 88226d9fe821
parent 331 f5461f8bc59b
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.
athos@331
     1
#ifndef HUGO_PREFLOW_PUSH_HH
athos@331
     2
#define HUGO_PREFLOW_PUSH_HH
athos@36
     3
athos@331
     4
//#include <algorithm>
athos@36
     5
#include <list>
athos@36
     6
#include <vector>
athos@331
     7
#include <queue>
athos@36
     8
//#include "pf_hiba.hh"
athos@36
     9
//#include <marci_list_graph.hh>
athos@77
    10
//#include <marci_graph_traits.hh>
athos@331
    11
#include <invalid.h>
athos@331
    12
#include <graph_wrapper.h>
athos@331
    13
//#include <reverse_bfs.hh>
athos@36
    14
athos@36
    15
using namespace std;
athos@36
    16
alpar@105
    17
namespace hugo {
athos@36
    18
athos@331
    19
  template <typename Graph, typename T>
athos@36
    20
  class preflow_push {
athos@36
    21
athos@331
    22
    //Useful typedefs
athos@331
    23
    typedef typename Graph::Node Node;
athos@331
    24
    typedef typename Graph::NodeIt NodeIt;
athos@331
    25
    typedef typename Graph::Edge Edge;
athos@331
    26
    typedef typename Graph::OutEdgeIt OutEdgeIt;
athos@331
    27
    typedef typename Graph::InEdgeIt InEdgeIt;
athos@505
    28
    typedef typename Graph::EdgeMap<T> CapacityType;
athos@505
    29
athos@505
    30
    typedef ResGraphWrapper<const Graph,int,CapacityType,CapacityType> ResGraphType;
athos@77
    31
athos@77
    32
athos@36
    33
    //---------------------------------------------
athos@36
    34
    //Parameters of the algorithm
athos@36
    35
    //---------------------------------------------
athos@36
    36
    //Fully examine an active node until excess becomes 0
athos@36
    37
    enum node_examination_t {examine_full, examine_to_relabel};
athos@36
    38
    //No more implemented yet:, examine_only_one_edge};
athos@36
    39
    node_examination_t node_examination;
athos@36
    40
    //Which implementation to be used
athos@36
    41
    enum implementation_t {impl_fifo, impl_highest_label};
athos@36
    42
    //No more implemented yet:};
athos@36
    43
    implementation_t implementation;
athos@36
    44
    //---------------------------------------------
athos@36
    45
    //Parameters of the algorithm
athos@36
    46
    //---------------------------------------------
athos@36
    47
 
athos@36
    48
  private:
athos@36
    49
    //input
athos@331
    50
    Graph& G;
athos@331
    51
    Node s;
athos@331
    52
    Node t;
athos@505
    53
    CapacityType &capacity;
athos@331
    54
athos@36
    55
    //output
athos@505
    56
    CapacityType preflow;
athos@36
    57
    T maxflow_value;
athos@36
    58
  
athos@36
    59
    //auxiliary variables for computation
athos@331
    60
    //The number of the nodes
athos@36
    61
    int number_of_nodes;
athos@331
    62
    //A nodemap for the level
athos@331
    63
    typename Graph::NodeMap<int> level;
athos@331
    64
    //A nodemap for the excess
athos@331
    65
    typename Graph::NodeMap<T> excess;
athos@36
    66
    
athos@36
    67
    //Number of nodes on each level
athos@36
    68
    vector<int> num_of_nodes_on_level;
athos@36
    69
    
athos@36
    70
    //For the FIFO implementation
athos@331
    71
    list<Node> fifo_nodes;
athos@36
    72
    //For 'highest label' implementation
athos@36
    73
    int highest_active;
athos@36
    74
    //int second_highest_active;
athos@331
    75
    vector< list<Node> > active_nodes;
athos@36
    76
athos@36
    77
  public:
athos@36
    78
  
athos@36
    79
    //Constructing the object using the graph, source, sink and capacity vector
athos@36
    80
    preflow_push(
athos@331
    81
		      Graph& _G, 
athos@331
    82
		      Node _s, 
athos@331
    83
		      Node _t, 
athos@331
    84
		      typename Graph::EdgeMap<T> & _capacity)
athos@36
    85
      : G(_G), s(_s), t(_t), 
athos@36
    86
	capacity(_capacity), 
athos@36
    87
	preflow(_G),
athos@36
    88
	//Counting the number of nodes
athos@77
    89
	//number_of_nodes(count(G.first<EachNodeIt>())),
athos@77
    90
	number_of_nodes(G.nodeNum()),
athos@77
    91
athos@36
    92
	level(_G),
athos@36
    93
	excess(_G)//,
athos@36
    94
        // Default constructor: active_nodes()
athos@36
    95
    { 
athos@36
    96
      //Simplest parameter settings
athos@36
    97
      node_examination = examine_full;//examine_to_relabel;//
athos@36
    98
      //Which implementation to be usedexamine_full
athos@36
    99
      implementation = impl_highest_label;//impl_fifo;
athos@36
   100
 
athos@36
   101
      //
athos@36
   102
      num_of_nodes_on_level.resize(2*number_of_nodes-1);
athos@36
   103
      num_of_nodes_on_level.clear();
athos@36
   104
athos@36
   105
      switch(implementation){
athos@36
   106
      case impl_highest_label :{
athos@331
   107
	active_nodes.clear();
athos@36
   108
	active_nodes.resize(2*number_of_nodes-1);
athos@331
   109
	
athos@36
   110
	break;
athos@36
   111
      }
athos@36
   112
      default:
athos@36
   113
	break;
athos@36
   114
      }
athos@36
   115
athos@36
   116
    }
athos@36
   117
athos@36
   118
    //Returns the value of a maximal flow 
athos@36
   119
    T run();
athos@36
   120
  
athos@331
   121
    typename Graph::EdgeMap<T>  getmaxflow(){
athos@36
   122
      return preflow;
athos@36
   123
    }
athos@36
   124
athos@36
   125
athos@36
   126
  private:
athos@36
   127
    //For testing purposes only
athos@36
   128
    //Lists the node_properties
athos@331
   129
    void write_property_vector(typename Graph::NodeMap<T> a,
athos@331
   130
			       //node_property_vector<Graph, T> a, 
athos@36
   131
			       char* prop_name="property"){
athos@331
   132
      for(NodeIt i=G.template first<NodeIt>(); G.valid(i); G.next(i)) {
athos@331
   133
	cout<<"Node id.: "<<G.id(i)<<", "<<prop_name<<" value: "<<a[i]<<endl;
athos@36
   134
      }
athos@36
   135
      cout<<endl;
athos@36
   136
    }
athos@505
   137
    /*
athos@36
   138
    //Modifies the excess of the node and makes sufficient changes
athos@331
   139
    void modify_excess(const Node& a ,T v){
athos@331
   140
      //T old_value=excess[a];
athos@331
   141
      excess[a] += v;
athos@36
   142
    }
athos@36
   143
  
athos@36
   144
    //This private procedure is supposed to modify the preflow on edge j
athos@36
   145
    //by value v (which can be positive or negative as well) 
athos@36
   146
    //and maintain the excess on the head and tail
athos@36
   147
    //Here we do not check whether this is possible or not
athos@331
   148
    void modify_preflow(Edge j, const T& v){
athos@36
   149
athos@36
   150
      //Modifiyng the edge
athos@331
   151
      preflow[j] += v;
athos@36
   152
athos@36
   153
athos@36
   154
      //Modifiyng the head
athos@36
   155
      modify_excess(G.head(j),v);
athos@36
   156
	
athos@36
   157
      //Modifiyng the tail
athos@36
   158
      modify_excess(G.tail(j),-v);
athos@36
   159
athos@36
   160
    }
athos@505
   161
    */
athos@36
   162
    //Gives the active node to work with 
athos@36
   163
    //(depending on the implementation to be used)
athos@331
   164
    Node get_active_node(){
athos@119
   165
      
athos@36
   166
athos@36
   167
      switch(implementation) {
athos@36
   168
      case impl_highest_label : {
athos@36
   169
athos@331
   170
	//First need to find the highest label for which there's an active node
athos@36
   171
	while( highest_active>=0 && active_nodes[highest_active].empty() ){ 
athos@36
   172
	  --highest_active;
athos@36
   173
	}
athos@36
   174
athos@36
   175
	if( highest_active>=0) {
athos@119
   176
	  
athos@119
   177
athos@331
   178
	  Node a=active_nodes[highest_active].front();
athos@36
   179
	  active_nodes[highest_active].pop_front();
athos@119
   180
	  
athos@36
   181
	  return a;
athos@36
   182
	}
athos@36
   183
	else {
athos@331
   184
	  return INVALID;
athos@36
   185
	}
athos@36
   186
	
athos@36
   187
	break;
athos@36
   188
	
athos@36
   189
      }
athos@36
   190
      case impl_fifo : {
athos@36
   191
athos@36
   192
	if( ! fifo_nodes.empty() ) {
athos@331
   193
	  Node a=fifo_nodes.front();
athos@36
   194
	  fifo_nodes.pop_front();
athos@36
   195
	  return a;
athos@36
   196
	}
athos@36
   197
	else {
athos@331
   198
	  return INVALID;
athos@36
   199
	}
athos@36
   200
	break;
athos@36
   201
      }
athos@36
   202
      }
athos@36
   203
      //
athos@331
   204
      return INVALID;
athos@36
   205
    }
athos@36
   206
athos@36
   207
    //Puts node 'a' among the active nodes
athos@331
   208
    void make_active(const Node& a){
athos@36
   209
      //s and t never become active
athos@36
   210
      if (a!=s && a!= t){
athos@36
   211
	switch(implementation){
athos@36
   212
	case impl_highest_label :
athos@331
   213
	  active_nodes[level[a]].push_back(a);
athos@36
   214
	  break;
athos@36
   215
	case impl_fifo :
athos@36
   216
	  fifo_nodes.push_back(a);
athos@36
   217
	  break;
athos@36
   218
	}
athos@36
   219
athos@36
   220
      }
athos@36
   221
athos@36
   222
      //Update highest_active label
athos@331
   223
      if (highest_active<level[a]){
athos@331
   224
	highest_active=level[a];
athos@36
   225
      }
athos@36
   226
athos@36
   227
    }
athos@36
   228
athos@36
   229
    //Changes the level of node a and make sufficent changes
athos@331
   230
    void change_level_to(Node a, int new_value){
athos@331
   231
      int seged = level[a];
athos@77
   232
      level.set(a,new_value);
athos@36
   233
      --num_of_nodes_on_level[seged];
athos@36
   234
      ++num_of_nodes_on_level[new_value];
athos@36
   235
    }
athos@36
   236
athos@36
   237
    //Collection of things useful (or necessary) to do before running
athos@77
   238
athos@36
   239
    void preprocess(){
athos@36
   240
athos@36
   241
      //---------------------------------------
athos@36
   242
      //Initialize parameters
athos@36
   243
      //---------------------------------------
athos@36
   244
athos@36
   245
      //Setting starting preflow, level and excess values to zero
athos@36
   246
      //This can be important, if the algorithm is run more then once
athos@331
   247
      for(NodeIt i=G.template first<NodeIt>(); G.valid(i); G.next(i)) {
athos@77
   248
        level.set(i,0);
athos@77
   249
        excess.set(i,0);
athos@331
   250
	for(OutEdgeIt j=G.template first<OutEdgeIt>(i); G.valid(j); G.next(j)) 
athos@77
   251
	  preflow.set(j, 0);
athos@36
   252
      }
athos@36
   253
      num_of_nodes_on_level[0]=number_of_nodes;
athos@36
   254
      highest_active=0;
athos@36
   255
      //---------------------------------------
athos@36
   256
      //Initialize parameters
athos@36
   257
      //---------------------------------------
athos@36
   258
athos@36
   259
      
athos@36
   260
      //------------------------------------
athos@36
   261
      //This is the only part that uses BFS
athos@36
   262
      //------------------------------------
athos@331
   263
athos@331
   264
      /*Reverse_bfs from t, to find the starting level.*/
athos@331
   265
      //Copyright: Jacint
athos@331
   266
      change_level_to(t,0);
athos@331
   267
athos@331
   268
      std::queue<Node> bfs_queue;
athos@331
   269
      bfs_queue.push(t);
athos@331
   270
athos@331
   271
      while (!bfs_queue.empty()) {
athos@331
   272
athos@331
   273
	Node v=bfs_queue.front();	
athos@331
   274
	bfs_queue.pop();
athos@331
   275
	int l=level[v]+1;
athos@331
   276
athos@331
   277
	InEdgeIt e;
athos@331
   278
	for(G.first(e,v); G.valid(e); G.next(e)) {
athos@331
   279
	  Node w=G.tail(e);
athos@331
   280
	  if ( level[w] == number_of_nodes && w != s ) {
athos@331
   281
	    bfs_queue.push(w);
athos@331
   282
	    //Node first=level_list[l];
athos@331
   283
	    //if ( G.valid(first) ) left.set(first,w);
athos@331
   284
	    //right.set(w,first);
athos@331
   285
	    //level_list[l]=w;
athos@331
   286
	    change_level_to(w, l);
athos@331
   287
	    //level.set(w, l);
athos@331
   288
	  }
athos@331
   289
	}
athos@331
   290
      }
athos@331
   291
      change_level_to(s,number_of_nodes);
athos@331
   292
      //level.set(s,number_of_nodes);
athos@331
   293
athos@331
   294
      /*
athos@36
   295
      //Setting starting level values using reverse bfs
athos@331
   296
      reverse_bfs<Graph> rev_bfs(G,t);
athos@36
   297
      rev_bfs.run();
athos@36
   298
      //write_property_vector(rev_bfs.dist,"rev_bfs");
athos@331
   299
      for(NodeIt i=G.template first<NodeIt>(); G.valid(i); G.next(i)) {
athos@36
   300
        change_level_to(i,rev_bfs.dist(i));
athos@36
   301
	//level.put(i,rev_bfs.dist.get(i));
athos@36
   302
      }
athos@331
   303
      */
athos@36
   304
      //------------------------------------
athos@36
   305
      //This is the only part that uses BFS
athos@36
   306
      //------------------------------------
athos@36
   307
      
athos@36
   308
      
athos@36
   309
      //Starting level of s
athos@36
   310
      change_level_to(s,number_of_nodes);
athos@36
   311
      //level.put(s,number_of_nodes);
athos@36
   312
      
athos@36
   313
      
athos@36
   314
      //we push as much preflow from s as possible to start with
athos@331
   315
      for(OutEdgeIt j=G.template first<OutEdgeIt>(s); G.valid(j); G.next(j)){ 
athos@331
   316
	modify_preflow(j,capacity[j] );
athos@36
   317
	make_active(G.head(j));
athos@331
   318
	int lev=level[G.head(j)];
athos@36
   319
	if(highest_active<lev){
athos@36
   320
	  highest_active=lev;
athos@36
   321
	}
athos@36
   322
      }
athos@36
   323
      //cout<<highest_active<<endl;
athos@36
   324
    } 
athos@36
   325
athos@36
   326
    
athos@36
   327
    //If the preflow is less than the capacity on the given edge
athos@36
   328
    //then it is an edge in the residual graph
athos@331
   329
    bool is_admissible_forward_edge(Edge j, int& new_level){
athos@119
   330
athos@331
   331
      if (capacity[j]>preflow[j]){
athos@331
   332
	if(level[G.tail(j)]==level[G.head(j)]+1){
athos@36
   333
	  return true;
athos@36
   334
	}
athos@36
   335
	else{
athos@331
   336
	  if (level[G.head(j)] < new_level)
athos@331
   337
	    new_level=level[G.head(j)];
athos@36
   338
	}
athos@36
   339
      }
athos@36
   340
      return false;
athos@36
   341
    }
athos@36
   342
athos@36
   343
    //If the preflow is greater than 0 on the given edge
athos@36
   344
    //then the edge reversd is an edge in the residual graph
athos@331
   345
    bool is_admissible_backward_edge(Edge j, int& new_level){
athos@119
   346
      
athos@331
   347
      if (0<preflow[j]){
athos@331
   348
	if(level[G.tail(j)]==level[G.head(j)]-1){
athos@119
   349
	 
athos@36
   350
	  return true;
athos@36
   351
	}
athos@36
   352
	else{
athos@331
   353
	  if (level[G.tail(j)] < new_level)
athos@331
   354
	    new_level=level[G.tail(j)];
athos@36
   355
	}
athos@36
   356
	
athos@36
   357
      }
athos@36
   358
      return false;
athos@36
   359
    }
athos@36
   360
athos@36
   361
 
athos@36
   362
  };  //class preflow_push  
athos@36
   363
athos@331
   364
  template<typename Graph, typename T>
athos@331
   365
    T preflow_push<Graph, T>::run() {
athos@331
   366
    
athos@331
   367
    //We need a residual graph
athos@331
   368
    ResGraphType res_graph(G, preflow, capacity);
athos@36
   369
    
athos@36
   370
    preprocess();
athos@119
   371
    //write_property_vector(level,"level");
athos@36
   372
    T e,v;
athos@331
   373
    Node a;
athos@331
   374
    while (a=get_active_node(), G.valid(a)){
athos@119
   375
      
athos@331
   376
      bool go_to_next_node=false;
athos@331
   377
      e = excess[a];
athos@331
   378
      while (!go_to_next_node){
athos@36
   379
athos@77
   380
	//Initial value for the new level for the active node we are dealing with
athos@77
   381
	int new_level=2*number_of_nodes;
athos@331
   382
athos@331
   383
athos@36
   384
	//Out edges from node a
athos@36
   385
	{
athos@505
   386
	  ResGraphType::OutEdgeIt j=res_graph.first(j,a);
athos@505
   387
	  while (res_graph.valid(j) && e){
athos@505
   388
	    if (is_admissible_forward_edge(j,new_level)){
athos@505
   389
	      v=min(e,res_graph.resCap(j));
athos@505
   390
	      e -= v;
athos@505
   391
	      //New node might become active
athos@505
   392
	      if (excess[res_graph.head(j)]==0){
athos@505
   393
		make_active(res_graph.head(j));
athos@505
   394
	      }
athos@505
   395
	      res_graph.augment(j,v);
athos@505
   396
	      excess[res_graph.tail(j)] -= v;
athos@505
   397
	      excess[res_graph.head(j)] += v;
athos@505
   398
	    }
athos@505
   399
	    res_graph.next(j);
athos@505
   400
	  }
athos@505
   401
	}
athos@505
   402
athos@505
   403
	/*
athos@505
   404
	//Out edges from node a
athos@505
   405
	{
athos@77
   406
	  OutEdgeIt j=G.template first<OutEdgeIt>(a);
athos@331
   407
	  while (G.valid(j) && e){
athos@36
   408
athos@36
   409
	    if (is_admissible_forward_edge(j,new_level)){
athos@331
   410
	      v=min(e,capacity[j] - preflow[j]);
athos@36
   411
	      e -= v;
athos@36
   412
	      //New node might become active
athos@331
   413
	      if (excess[G.head(j)]==0){
athos@36
   414
		make_active(G.head(j));
athos@36
   415
	      }
athos@36
   416
	      modify_preflow(j,v);
athos@36
   417
	    }
athos@331
   418
	    G.next(j);
athos@36
   419
	  }
athos@36
   420
	}
athos@36
   421
	//In edges to node a
athos@36
   422
	{
athos@77
   423
	  InEdgeIt j=G.template first<InEdgeIt>(a);
athos@331
   424
	  while (G.valid(j) && e){
athos@36
   425
	    if (is_admissible_backward_edge(j,new_level)){
athos@331
   426
	      v=min(e,preflow[j]);
athos@36
   427
	      e -= v;
athos@36
   428
	      //New node might become active
athos@331
   429
	      if (excess[G.tail(j)]==0){
athos@36
   430
		make_active(G.tail(j));
athos@36
   431
	      }
athos@36
   432
	      modify_preflow(j,-v);
athos@36
   433
	    }
athos@331
   434
	    G.next(j);
athos@36
   435
	  }
athos@36
   436
	}
athos@505
   437
	*/
athos@36
   438
athos@119
   439
	//if (G.id(a)==999)
athos@119
   440
	//cout<<new_level<<" e: "<<e<<endl;
athos@36
   441
	//cout<<G.id(a)<<" "<<new_level<<endl;
athos@36
   442
athos@36
   443
	if (0==e){
athos@36
   444
	  //Saturating push
athos@36
   445
	  go_to_next_node=true;
athos@36
   446
	}
athos@36
   447
	else{//If there is still excess in node a
athos@77
   448
	  
athos@77
   449
	  //change_level_to(a,new_level+1);
athos@77
   450
	  
athos@36
   451
	  //Level remains empty
athos@331
   452
	  if (num_of_nodes_on_level[level[a]]==1){
athos@36
   453
	    change_level_to(a,number_of_nodes);
athos@36
   454
	    //go_to_next_node=True;
athos@36
   455
	  }
athos@36
   456
	  else{
athos@36
   457
	    change_level_to(a,new_level+1);
athos@36
   458
	    //increase_level(a);
athos@36
   459
	  }
athos@77
   460
	  
athos@36
   461
    
athos@36
   462
	  
athos@36
   463
athos@36
   464
	  switch(node_examination){
athos@36
   465
	  case examine_to_relabel:
athos@36
   466
	    make_active(a);
athos@36
   467
athos@36
   468
	    go_to_next_node = true;
athos@36
   469
	    break;
athos@36
   470
	  default:
athos@36
   471
	    break;
athos@36
   472
	  }
athos@36
   473
	  
athos@36
   474
    
athos@36
   475
	
athos@36
   476
	}//if (0==e)
athos@36
   477
      }
athos@36
   478
    }
athos@331
   479
    maxflow_value = excess[t];
athos@36
   480
    return maxflow_value;
athos@36
   481
  }//run
athos@36
   482
athos@36
   483
alpar@105
   484
}//namespace hugo
athos@36
   485
athos@36
   486
#endif //PREFLOW_PUSH_HH