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

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

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