src/work/edmonds_karp.h
author marci
Fri, 12 Mar 2004 16:37:08 +0000
changeset 179 91646df36ffc
parent 174 44700ed9ffaa
child 191 efea403c9595
permissions -rw-r--r--
const
marci@174
     1
// -*- c++ -*-
marci@174
     2
#ifndef EDMONDS_KARP_H
marci@174
     3
#define EDMONDS_KARP_H
marci@174
     4
marci@174
     5
#include <algorithm>
marci@174
     6
#include <list>
marci@174
     7
#include <iterator>
marci@174
     8
marci@174
     9
#include <bfs_iterator.h>
marci@174
    10
#include <invalid.h>
marci@174
    11
marci@174
    12
namespace hugo {
marci@174
    13
marci@174
    14
  template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
marci@174
    15
  class ResGraph {
marci@174
    16
  public:
marci@174
    17
    typedef typename Graph::Node Node;
marci@174
    18
    typedef typename Graph::NodeIt NodeIt;
marci@174
    19
  private:
marci@174
    20
    typedef typename Graph::SymEdgeIt OldSymEdgeIt;
marci@174
    21
    const Graph& G;
marci@174
    22
    FlowMap& flow;
marci@174
    23
    const CapacityMap& capacity;
marci@174
    24
  public:
marci@174
    25
    ResGraph(const Graph& _G, FlowMap& _flow, 
marci@174
    26
	     const CapacityMap& _capacity) : 
marci@174
    27
      G(_G), flow(_flow), capacity(_capacity) { }
marci@174
    28
marci@174
    29
    class Edge; 
marci@174
    30
    class OutEdgeIt; 
marci@174
    31
    friend class Edge; 
marci@174
    32
    friend class OutEdgeIt; 
marci@174
    33
marci@174
    34
    class Edge {
marci@174
    35
      friend class ResGraph<Graph, Number, FlowMap, CapacityMap>;
marci@174
    36
    protected:
marci@174
    37
      const ResGraph<Graph, Number, FlowMap, CapacityMap>* resG;
marci@174
    38
      OldSymEdgeIt sym;
marci@174
    39
    public:
marci@174
    40
      Edge() { } 
marci@174
    41
      //Edge(const Edge& e) : resG(e.resG), sym(e.sym) { }
marci@174
    42
      Number free() const { 
marci@174
    43
	if (resG->G.aNode(sym)==resG->G.tail(sym)) { 
marci@174
    44
	  return (resG->capacity.get(sym)-resG->flow.get(sym)); 
marci@174
    45
	} else { 
marci@174
    46
	  return (resG->flow.get(sym)); 
marci@174
    47
	}
marci@174
    48
      }
marci@174
    49
      bool valid() const { return sym.valid(); }
marci@174
    50
      void augment(Number a) const {
marci@174
    51
	if (resG->G.aNode(sym)==resG->G.tail(sym)) { 
marci@174
    52
	  resG->flow.set(sym, resG->flow.get(sym)+a);
marci@174
    53
	  //resG->flow[sym]+=a;
marci@174
    54
	} else { 
marci@174
    55
	  resG->flow.set(sym, resG->flow.get(sym)-a);
marci@174
    56
	  //resG->flow[sym]-=a;
marci@174
    57
	}
marci@174
    58
      }
marci@174
    59
    };
marci@174
    60
marci@174
    61
    class OutEdgeIt : public Edge {
marci@174
    62
      friend class ResGraph<Graph, Number, FlowMap, CapacityMap>;
marci@174
    63
    public:
marci@174
    64
      OutEdgeIt() { }
marci@174
    65
      //OutEdgeIt(const OutEdgeIt& e) { resG=e.resG; sym=e.sym; }
marci@174
    66
    private:
marci@174
    67
      OutEdgeIt(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _resG, Node v) { 
marci@174
    68
      	resG=&_resG;
marci@174
    69
	sym=resG->G.template first<OldSymEdgeIt>(v);
marci@174
    70
	while( sym.valid() && !(free()>0) ) { ++sym; }
marci@174
    71
      }
marci@174
    72
    public:
marci@174
    73
      OutEdgeIt& operator++() { 
marci@174
    74
	++sym; 
marci@174
    75
	while( sym.valid() && !(free()>0) ) { ++sym; }
marci@174
    76
	return *this; 
marci@174
    77
      }
marci@174
    78
    };
marci@174
    79
marci@174
    80
    void /*getF*/first(OutEdgeIt& e, Node v) const { 
marci@174
    81
      e=OutEdgeIt(*this, v); 
marci@174
    82
    }
marci@174
    83
    void /*getF*/first(NodeIt& v) const { G./*getF*/first(v); }
marci@174
    84
    
marci@174
    85
    template< typename It >
marci@174
    86
    It first() const { 
marci@174
    87
      It e;      
marci@174
    88
      /*getF*/first(e);
marci@174
    89
      return e; 
marci@174
    90
    }
marci@174
    91
marci@174
    92
    template< typename It >
marci@174
    93
    It first(Node v) const { 
marci@174
    94
      It e;
marci@174
    95
      /*getF*/first(e, v);
marci@174
    96
      return e; 
marci@174
    97
    }
marci@174
    98
marci@174
    99
    Node tail(Edge e) const { return G.aNode(e.sym); }
marci@174
   100
    Node head(Edge e) const { return G.bNode(e.sym); }
marci@174
   101
marci@174
   102
    Node aNode(OutEdgeIt e) const { return G.aNode(e.sym); }
marci@174
   103
    Node bNode(OutEdgeIt e) const { return G.bNode(e.sym); }
marci@174
   104
marci@174
   105
    int id(Node v) const { return G.id(v); }
marci@174
   106
marci@174
   107
    template <typename S>
marci@174
   108
    class NodeMap {
marci@174
   109
      typename Graph::NodeMap<S> node_map; 
marci@174
   110
    public:
marci@174
   111
      NodeMap(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _G) : node_map(_G.G) { }
marci@174
   112
      NodeMap(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _G, S a) : node_map(_G.G, a) { }
marci@174
   113
      void set(Node nit, S a) { node_map.set(nit, a); }
marci@174
   114
      S get(Node nit) const { return node_map.get(nit); }
marci@174
   115
      S& operator[](Node nit) { return node_map[nit]; } 
marci@174
   116
      const S& operator[](Node nit) const { return node_map[nit]; } 
marci@174
   117
    };
marci@174
   118
marci@174
   119
  };
marci@174
   120
marci@174
   121
marci@174
   122
  template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
marci@174
   123
  class ResGraph2 {
marci@174
   124
  public:
marci@174
   125
    typedef typename Graph::Node Node;
marci@174
   126
    typedef typename Graph::NodeIt NodeIt;
marci@174
   127
  private:
marci@174
   128
    //typedef typename Graph::SymEdgeIt OldSymEdgeIt;
marci@174
   129
    typedef typename Graph::OutEdgeIt OldOutEdgeIt;
marci@174
   130
    typedef typename Graph::InEdgeIt OldInEdgeIt;
marci@174
   131
    
marci@174
   132
    const Graph& G;
marci@174
   133
    FlowMap& flow;
marci@174
   134
    const CapacityMap& capacity;
marci@174
   135
  public:
marci@174
   136
    ResGraph2(const Graph& _G, FlowMap& _flow, 
marci@174
   137
	     const CapacityMap& _capacity) : 
marci@174
   138
      G(_G), flow(_flow), capacity(_capacity) { }
marci@174
   139
marci@174
   140
    class Edge; 
marci@174
   141
    class OutEdgeIt; 
marci@174
   142
    friend class Edge; 
marci@174
   143
    friend class OutEdgeIt; 
marci@174
   144
marci@174
   145
    class Edge {
marci@174
   146
      friend class ResGraph2<Graph, Number, FlowMap, CapacityMap>;
marci@174
   147
    protected:
marci@174
   148
      const ResGraph2<Graph, Number, FlowMap, CapacityMap>* resG;
marci@174
   149
      //OldSymEdgeIt sym;
marci@174
   150
      OldOutEdgeIt out;
marci@174
   151
      OldInEdgeIt in;
marci@174
   152
      bool out_or_in; //true, iff out
marci@174
   153
    public:
marci@174
   154
      Edge() : out_or_in(true) { } 
marci@174
   155
      Number free() const { 
marci@174
   156
	if (out_or_in) { 
marci@174
   157
	  return (resG->capacity.get(out)-resG->flow.get(out)); 
marci@174
   158
	} else { 
marci@174
   159
	  return (resG->flow.get(in)); 
marci@174
   160
	}
marci@174
   161
      }
marci@174
   162
      bool valid() const { 
marci@174
   163
	return out_or_in && out.valid() || in.valid(); }
marci@174
   164
      void augment(Number a) const {
marci@174
   165
	if (out_or_in) { 
marci@174
   166
	  resG->flow.set(out, resG->flow.get(out)+a);
marci@174
   167
	} else { 
marci@174
   168
	  resG->flow.set(in, resG->flow.get(in)-a);
marci@174
   169
	}
marci@174
   170
      }
marci@174
   171
    };
marci@174
   172
marci@174
   173
    class OutEdgeIt : public Edge {
marci@174
   174
      friend class ResGraph2<Graph, Number, FlowMap, CapacityMap>;
marci@174
   175
    public:
marci@174
   176
      OutEdgeIt() { }
marci@174
   177
    private:
marci@174
   178
      OutEdgeIt(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _resG, Node v) { 
marci@174
   179
      	resG=&_resG;
marci@174
   180
	out=resG->G.template first<OldOutEdgeIt>(v);
marci@174
   181
	while( out.valid() && !(free()>0) ) { ++out; }
marci@174
   182
	if (!out.valid()) {
marci@174
   183
	  out_or_in=0;
marci@174
   184
	  in=resG->G.template first<OldInEdgeIt>(v);
marci@174
   185
	  while( in.valid() && !(free()>0) ) { ++in; }
marci@174
   186
	}
marci@174
   187
      }
marci@174
   188
    public:
marci@174
   189
      OutEdgeIt& operator++() { 
marci@174
   190
	if (out_or_in) {
marci@174
   191
	  Node v=resG->G.aNode(out);
marci@174
   192
	  ++out;
marci@174
   193
	  while( out.valid() && !(free()>0) ) { ++out; }
marci@174
   194
	  if (!out.valid()) {
marci@174
   195
	    out_or_in=0;
marci@174
   196
	    in=resG->G.template first<OldInEdgeIt>(v);
marci@174
   197
	    while( in.valid() && !(free()>0) ) { ++in; }
marci@174
   198
	  }
marci@174
   199
	} else {
marci@174
   200
	  ++in;
marci@174
   201
	  while( in.valid() && !(free()>0) ) { ++in; } 
marci@174
   202
	}
marci@174
   203
	return *this; 
marci@174
   204
      }
marci@174
   205
    };
marci@174
   206
marci@174
   207
    void /*getF*/first(OutEdgeIt& e, Node v) const { 
marci@174
   208
      e=OutEdgeIt(*this, v); 
marci@174
   209
    }
marci@174
   210
    void /*getF*/first(NodeIt& v) const { G./*getF*/first(v); }
marci@174
   211
    
marci@174
   212
    template< typename It >
marci@174
   213
    It first() const { 
marci@174
   214
      It e;
marci@174
   215
      /*getF*/first(e);
marci@174
   216
      return e; 
marci@174
   217
    }
marci@174
   218
marci@174
   219
    template< typename It >
marci@174
   220
    It first(Node v) const { 
marci@174
   221
      It e;
marci@174
   222
      /*getF*/first(e, v);
marci@174
   223
      return e; 
marci@174
   224
    }
marci@174
   225
marci@174
   226
    Node tail(Edge e) const { 
marci@174
   227
      return ((e.out_or_in) ? G.aNode(e.out) : G.aNode(e.in)); }
marci@174
   228
    Node head(Edge e) const { 
marci@174
   229
      return ((e.out_or_in) ? G.bNode(e.out) : G.bNode(e.in)); }
marci@174
   230
marci@174
   231
    Node aNode(OutEdgeIt e) const { 
marci@174
   232
      return ((e.out_or_in) ? G.aNode(e.out) : G.aNode(e.in)); }
marci@174
   233
    Node bNode(OutEdgeIt e) const { 
marci@174
   234
      return ((e.out_or_in) ? G.bNode(e.out) : G.bNode(e.in)); }
marci@174
   235
marci@174
   236
    int id(Node v) const { return G.id(v); }
marci@174
   237
marci@174
   238
    template <typename S>
marci@174
   239
    class NodeMap {
marci@174
   240
      typename Graph::NodeMap<S> node_map; 
marci@174
   241
    public:
marci@174
   242
      NodeMap(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _G) : node_map(_G.G) { }
marci@174
   243
      NodeMap(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _G, S a) : node_map(_G.G, a) { }
marci@174
   244
      void set(Node nit, S a) { node_map.set(nit, a); }
marci@174
   245
      S get(Node nit) const { return node_map.get(nit); }
marci@174
   246
    };
marci@174
   247
  };
marci@174
   248
marci@174
   249
marci@174
   250
  template <typename Graph, typename Number, typename FlowMap, typename CapacityMap>
marci@174
   251
  class MaxFlow {
marci@174
   252
  public:
marci@174
   253
    typedef typename Graph::Node Node;
marci@174
   254
    typedef typename Graph::Edge Edge;
marci@174
   255
    typedef typename Graph::EdgeIt EdgeIt;
marci@174
   256
    typedef typename Graph::OutEdgeIt OutEdgeIt;
marci@174
   257
    typedef typename Graph::InEdgeIt InEdgeIt;
marci@174
   258
marci@174
   259
  private:
marci@174
   260
    const Graph* G;
marci@174
   261
    Node s;
marci@174
   262
    Node t;
marci@174
   263
    FlowMap* flow;
marci@174
   264
    const CapacityMap* capacity;
marci@174
   265
    typedef ResGraphWrapper<Graph, Number, FlowMap, CapacityMap > AugGraph;
marci@174
   266
    typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
marci@174
   267
    typedef typename AugGraph::Edge AugEdge;
marci@174
   268
marci@174
   269
    //AugGraph res_graph;    
marci@174
   270
    //typedef typename AugGraph::NodeMap<bool> ReachedMap;
marci@174
   271
    //typename AugGraph::NodeMap<AugEdge> pred; 
marci@174
   272
    //typename AugGraph::NodeMap<Number> free;
marci@174
   273
  public:
marci@174
   274
    MaxFlow(const Graph& _G, Node _s, Node _t, FlowMap& _flow, const CapacityMap& _capacity) : 
marci@174
   275
      G(&_G), s(_s), t(_t), flow(&_flow), capacity(&_capacity) //,  
marci@174
   276
      //res_graph(G, flow, capacity), pred(res_graph), free(res_graph) 
marci@174
   277
      { }
marci@174
   278
    bool augmentOnShortestPath() {
marci@174
   279
      AugGraph res_graph(*G, *flow, *capacity);
marci@174
   280
      bool _augment=false;
marci@174
   281
      
marci@174
   282
      typedef typename AugGraph::NodeMap<bool> ReachedMap;
marci@174
   283
      BfsIterator5< AugGraph, /*AugOutEdgeIt,*/ ReachedMap > res_bfs(res_graph);
marci@174
   284
      res_bfs.pushAndSetReached(s);
marci@174
   285
	
marci@174
   286
      typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
marci@174
   287
      pred.set(s, AugEdge(INVALID));
marci@174
   288
      
marci@174
   289
      typename AugGraph::NodeMap<Number> free(res_graph);
marci@174
   290
	
marci@174
   291
      //searching for augmenting path
marci@174
   292
      while ( !res_bfs.finished() ) { 
marci@174
   293
	AugOutEdgeIt e=/*AugOutEdgeIt*/(res_bfs);
marci@174
   294
	if (res_graph.valid(e) && res_bfs.isBNodeNewlyReached()) {
marci@174
   295
	  Node v=res_graph.tail(e);
marci@174
   296
	  Node w=res_graph.head(e);
marci@174
   297
	  pred.set(w, e);
marci@174
   298
	  if (res_graph.valid(pred.get(v))) {
marci@174
   299
	    free.set(w, std::min(free.get(v), res_graph.free(e)));
marci@174
   300
	  } else {
marci@174
   301
	    free.set(w, res_graph.free(e)); 
marci@174
   302
	  }
marci@174
   303
	  if (res_graph.head(e)==t) { _augment=true; break; }
marci@174
   304
	}
marci@174
   305
	
marci@174
   306
	++res_bfs;
marci@174
   307
      } //end of searching augmenting path
marci@174
   308
marci@174
   309
      if (_augment) {
marci@174
   310
	Node n=t;
marci@174
   311
	Number augment_value=free.get(t);
marci@174
   312
	while (res_graph.valid(pred.get(n))) { 
marci@174
   313
	  AugEdge e=pred.get(n);
marci@174
   314
	  res_graph.augment(e, augment_value); 
marci@174
   315
	  //e.augment(augment_value); 
marci@174
   316
	  n=res_graph.tail(e);
marci@174
   317
	}
marci@174
   318
      }
marci@174
   319
marci@174
   320
      return _augment;
marci@174
   321
    }
marci@174
   322
marci@174
   323
    template<typename MutableGraph> bool augmentOnBlockingFlow() {
marci@174
   324
      
marci@174
   325
//       std::cout << "number of nodes: " << G->nodeNum() << std::endl;
marci@174
   326
//       typename Graph::NodeIt n; 
marci@174
   327
//       G->first(n);
marci@174
   328
//       for( ; G->valid(n); G->next(n)) {
marci@174
   329
// 	std::cout << G->id(n) << std::endl;
marci@174
   330
//       }
marci@174
   331
//       std::cout << "meg elek 1";
marci@174
   332
marci@174
   333
//       for(typename Graph::NodeIt n=G->template first<typename Graph::NodeIt>(); G->valid(n); G->next(n)) {
marci@174
   334
// 	std::cout << G->id(n) << std::endl;
marci@174
   335
//       }
marci@174
   336
//       std::cout << "meg elek 2";
marci@174
   337
      
marci@174
   338
      bool _augment=false;
marci@174
   339
marci@174
   340
      AugGraph res_graph(*G, *flow, *capacity);
marci@174
   341
marci@174
   342
      typedef typename AugGraph::NodeMap<bool> ReachedMap;
marci@174
   343
      BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph);
marci@174
   344
marci@174
   345
      bfs.pushAndSetReached(s);
marci@174
   346
      typename AugGraph::NodeMap<int> dist(res_graph); //filled up with 0's
marci@174
   347
      while ( !bfs.finished() ) { 
marci@174
   348
	AugOutEdgeIt e=/*AugOutEdgeIt*/(bfs);
marci@174
   349
	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
marci@174
   350
	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
marci@174
   351
	}
marci@174
   352
	
marci@174
   353
	++bfs;
marci@174
   354
      } //computing distances from s in the residual graph
marci@174
   355
marci@174
   356
//       for(typename AugGraph::NodeIt n=res_graph.template first<typename AugGraph::NodeIt>(); res_graph.valid(n); res_graph.next(n)) {
marci@174
   357
// 	std::cout << res_graph.id(n) << std::endl;
marci@174
   358
//       }
marci@174
   359
//       std::cout << "meg elek";
marci@174
   360
marci@174
   361
      MutableGraph F;
marci@174
   362
      typename AugGraph::NodeMap<typename MutableGraph::Node> 
marci@174
   363
	res_graph_to_F(res_graph);
marci@174
   364
      for(typename AugGraph::NodeIt n=res_graph.template first<typename AugGraph::NodeIt>(); res_graph.valid(n); res_graph.next(n)) {
marci@174
   365
	res_graph_to_F.set(n, F.addNode());
marci@174
   366
      }
marci@174
   367
      
marci@174
   368
      typename MutableGraph::Node sF=res_graph_to_F.get(s);
marci@174
   369
      typename MutableGraph::Node tF=res_graph_to_F.get(t);
marci@174
   370
marci@174
   371
      typename MutableGraph::EdgeMap<AugEdge> original_edge(F);
marci@174
   372
      typename MutableGraph::EdgeMap<Number> residual_capacity(F);
marci@174
   373
marci@174
   374
      //Making F to the graph containing the edges of the residual graph 
marci@174
   375
      //which are in some shortest paths
marci@174
   376
      for(typename AugGraph::EdgeIt e=res_graph.template first<typename AugGraph::EdgeIt>(); res_graph.valid(e); res_graph.next(e)) {
marci@174
   377
	if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) {
marci@174
   378
	  typename MutableGraph::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
marci@174
   379
	  original_edge.update();
marci@174
   380
	  original_edge.set(f, e);
marci@174
   381
	  residual_capacity.update();
marci@174
   382
	  residual_capacity.set(f, res_graph.free(e));
marci@174
   383
	} 
marci@174
   384
      }
marci@174
   385
marci@174
   386
//       for(typename MutableGraph::NodeIt n=F.template first<typename MutableGraph::NodeIt>(); F.valid(n); F.next(n)) {
marci@174
   387
// 	std::cout << F.id(n) << std::endl;
marci@174
   388
//       }
marci@174
   389
marci@174
   390
      bool __augment=true;
marci@174
   391
marci@174
   392
      while (__augment) {
marci@174
   393
	__augment=false;
marci@174
   394
	//computing blocking flow with dfs
marci@174
   395
	typedef typename MutableGraph::NodeMap<bool> BlockingReachedMap;
marci@174
   396
	DfsIterator4< MutableGraph, typename MutableGraph::OutEdgeIt, BlockingReachedMap > dfs(F);
marci@174
   397
	typename MutableGraph::NodeMap<typename MutableGraph::Edge> pred(F);
marci@174
   398
	pred.set(sF, typename MutableGraph::Edge(INVALID));
marci@174
   399
	//invalid iterators for sources
marci@174
   400
marci@174
   401
	typename MutableGraph::NodeMap<Number> free(F);
marci@174
   402
marci@174
   403
	dfs.pushAndSetReached(sF);      
marci@174
   404
	while (!dfs.finished()) {
marci@174
   405
	  ++dfs;
marci@174
   406
	  if (F.valid(typename MutableGraph::OutEdgeIt(dfs))) {
marci@174
   407
	    if (dfs.isBNodeNewlyReached()) {
marci@174
   408
// 	      std::cout << "OutEdgeIt: " << dfs; 
marci@174
   409
// 	      std::cout << " aNode: " << F.aNode(dfs); 
marci@174
   410
// 	      std::cout << " bNode: " << F.bNode(dfs) << " ";
marci@174
   411
	  
marci@174
   412
	      typename MutableGraph::Node v=F.aNode(dfs);
marci@174
   413
	      typename MutableGraph::Node w=F.bNode(dfs);
marci@174
   414
	      pred.set(w, dfs);
marci@174
   415
	      if (F.valid(pred.get(v))) {
marci@174
   416
		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
marci@174
   417
	      } else {
marci@174
   418
		free.set(w, residual_capacity.get(dfs)); 
marci@174
   419
	      }
marci@174
   420
	      if (w==tF) { 
marci@174
   421
		//std::cout << "AUGMENTATION"<<std::endl;
marci@174
   422
		__augment=true; 
marci@174
   423
		_augment=true;
marci@174
   424
		break; 
marci@174
   425
	      }
marci@174
   426
	      
marci@174
   427
	    } else {
marci@174
   428
	      F.erase(typename MutableGraph::OutEdgeIt(dfs));
marci@174
   429
	    }
marci@174
   430
	  } 
marci@174
   431
	}
marci@174
   432
marci@174
   433
	if (__augment) {
marci@174
   434
	  typename MutableGraph::Node n=tF;
marci@174
   435
	  Number augment_value=free.get(tF);
marci@174
   436
	  while (F.valid(pred.get(n))) { 
marci@174
   437
	    typename MutableGraph::Edge e=pred.get(n);
marci@174
   438
	    res_graph.augment(original_edge.get(e), augment_value); 
marci@174
   439
	    //original_edge.get(e).augment(augment_value); 
marci@174
   440
	    n=F.tail(e);
marci@174
   441
	    if (residual_capacity.get(e)==augment_value) 
marci@174
   442
	      F.erase(e); 
marci@174
   443
	    else 
marci@174
   444
	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
marci@174
   445
	  }
marci@174
   446
	}
marci@174
   447
	
marci@174
   448
      }
marci@174
   449
            
marci@174
   450
      return _augment;
marci@174
   451
    }
marci@174
   452
    bool augmentOnBlockingFlow2() {
marci@174
   453
      bool _augment=false;
marci@174
   454
marci@174
   455
      //typedef ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> EAugGraph;
marci@174
   456
      typedef FilterGraphWrapper< ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> > EAugGraph;
marci@174
   457
      typedef typename EAugGraph::OutEdgeIt EAugOutEdgeIt;
marci@174
   458
      typedef typename EAugGraph::Edge EAugEdge;
marci@174
   459
marci@174
   460
      EAugGraph res_graph(*G, *flow, *capacity);
marci@174
   461
marci@174
   462
      //std::cout << "meg jo1" << std::endl;
marci@174
   463
marci@174
   464
      //typedef typename EAugGraph::NodeMap<bool> ReachedMap;
marci@174
   465
      BfsIterator4< 
marci@174
   466
	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>, 
marci@175
   467
	typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt, 
marci@174
   468
	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<bool> > bfs(res_graph);
marci@174
   469
      
marci@174
   470
      //std::cout << "meg jo2" << std::endl;
marci@174
   471
marci@174
   472
      bfs.pushAndSetReached(s);
marci@174
   473
      //std::cout << "meg jo2.5" << std::endl;
marci@174
   474
marci@174
   475
      //typename EAugGraph::NodeMap<int> dist(res_graph); //filled up with 0's
marci@174
   476
      typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::
marci@174
   477
	NodeMap<int>& dist=res_graph.dist;
marci@174
   478
      //std::cout << "meg jo2.6" << std::endl;
marci@174
   479
marci@174
   480
      while ( !bfs.finished() ) {
marci@175
   481
	typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt e=bfs;
marci@174
   482
//	EAugOutEdgeIt e=/*AugOutEdgeIt*/(bfs);
marci@174
   483
 	//if (res_graph.valid(e)) {
marci@174
   484
 	//    std::cout<<"a:"<<res_graph.tail(e)<<"b:"<<res_graph.head(e)<<std::endl;
marci@174
   485
 	//}
marci@174
   486
	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
marci@174
   487
	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
marci@174
   488
	}
marci@174
   489
	
marci@174
   490
	++bfs;	
marci@174
   491
      } //computing distances from s in the residual graph
marci@174
   492
marci@174
   493
marci@174
   494
      //std::cout << "meg jo3" << std::endl;
marci@174
   495
marci@174
   496
//       typedef typename EAugGraph::NodeIt EAugNodeIt;
marci@174
   497
//       for(EAugNodeIt n=res_graph.template first<EAugNodeIt>(); res_graph.valid(n); res_graph.next(n)) {
marci@174
   498
// 	std::cout << "dist: " << dist.get(n) << std::endl;
marci@174
   499
//       }
marci@174
   500
marci@174
   501
      bool __augment=true;
marci@174
   502
marci@174
   503
      while (__augment) {
marci@174
   504
//	std::cout << "new iteration"<< std::endl;
marci@174
   505
marci@174
   506
	__augment=false;
marci@174
   507
	//computing blocking flow with dfs
marci@174
   508
	typedef typename EAugGraph::NodeMap<bool> BlockingReachedMap;
marci@174
   509
	DfsIterator4< EAugGraph, EAugOutEdgeIt, BlockingReachedMap > 
marci@174
   510
	  dfs(res_graph);
marci@174
   511
	typename EAugGraph::NodeMap<EAugEdge> pred(res_graph); 
marci@174
   512
	pred.set(s, EAugEdge(INVALID));
marci@174
   513
	//invalid iterators for sources
marci@174
   514
marci@174
   515
	typename EAugGraph::NodeMap<Number> free(res_graph);
marci@174
   516
marci@174
   517
	dfs.pushAndSetReached(s);
marci@174
   518
	while (!dfs.finished()) {
marci@174
   519
	  ++dfs;
marci@174
   520
	  if (res_graph.valid(EAugOutEdgeIt(dfs))) { 
marci@174
   521
	    if (dfs.isBNodeNewlyReached()) {
marci@174
   522
// 	      std::cout << "OutEdgeIt: " << dfs; 
marci@174
   523
// 	      std::cout << " aNode: " << res_graph.aNode(dfs); 
marci@174
   524
// 	      std::cout << " res cap: " << EAugOutEdgeIt(dfs).free(); 
marci@174
   525
// 	      std::cout << " bNode: " << res_graph.bNode(dfs) << " ";
marci@174
   526
	  
marci@174
   527
	      typename EAugGraph::Node v=res_graph.aNode(dfs);
marci@174
   528
	      typename EAugGraph::Node w=res_graph.bNode(dfs);
marci@174
   529
marci@174
   530
	      pred.set(w, EAugOutEdgeIt(dfs));
marci@174
   531
marci@174
   532
	      //std::cout << EAugOutEdgeIt(dfs).free() << std::endl;
marci@174
   533
	      if (res_graph.valid(pred.get(v))) {
marci@174
   534
		free.set(w, std::min(free.get(v), res_graph.free(/*EAugOutEdgeIt*/(dfs))));
marci@174
   535
	      } else {
marci@174
   536
		free.set(w, res_graph.free(/*EAugOutEdgeIt*/(dfs))); 
marci@174
   537
	      }
marci@174
   538
	      
marci@174
   539
	      if (w==t) { 
marci@174
   540
//		std::cout << "t is reached, AUGMENTATION"<<std::endl;
marci@174
   541
		__augment=true; 
marci@174
   542
		_augment=true;
marci@174
   543
		break; 
marci@174
   544
	      }
marci@174
   545
	    } else {
marci@174
   546
//	      std::cout << "<<DELETE ";
marci@174
   547
//	      std::cout << " aNode: " << res_graph.aNode(dfs); 
marci@174
   548
//	      std::cout << " res cap: " << EAugOutEdgeIt(dfs).free(); 
marci@174
   549
//	      std::cout << " bNode: " << res_graph.bNode(dfs) << " ";
marci@174
   550
//	      std::cout << "DELETE>> ";
marci@174
   551
marci@174
   552
	      res_graph.erase(dfs);
marci@174
   553
	    }
marci@174
   554
	  } 
marci@174
   555
marci@174
   556
	}
marci@174
   557
marci@174
   558
	if (__augment) {
marci@174
   559
	  typename EAugGraph::Node n=t;
marci@174
   560
	  Number augment_value=free.get(t);
marci@174
   561
//	  std::cout << "av:" << augment_value << std::endl;
marci@174
   562
	  while (res_graph.valid(pred.get(n))) { 
marci@174
   563
	    EAugEdge e=pred.get(n);
marci@174
   564
	    res_graph.augment(e, augment_value);
marci@174
   565
	    //e.augment(augment_value); 
marci@174
   566
	    n=res_graph.tail(e);
marci@174
   567
	    if (res_graph.free(e)==0)
marci@174
   568
	      res_graph.erase(e);
marci@174
   569
	  }
marci@174
   570
	}
marci@174
   571
      
marci@174
   572
      }
marci@174
   573
            
marci@174
   574
      return _augment;
marci@174
   575
    }
marci@174
   576
    void run() {
marci@174
   577
      //int num_of_augmentations=0;
marci@174
   578
      while (augmentOnShortestPath()) { 
marci@174
   579
	//while (augmentOnBlockingFlow<MutableGraph>()) { 
marci@174
   580
	//std::cout << ++num_of_augmentations << " ";
marci@174
   581
	//std::cout<<std::endl;
marci@174
   582
      } 
marci@174
   583
    }
marci@174
   584
    template<typename MutableGraph> void run() {
marci@174
   585
      //int num_of_augmentations=0;
marci@174
   586
      //while (augmentOnShortestPath()) { 
marci@174
   587
	while (augmentOnBlockingFlow<MutableGraph>()) { 
marci@174
   588
	//std::cout << ++num_of_augmentations << " ";
marci@174
   589
	//std::cout<<std::endl;
marci@174
   590
      } 
marci@174
   591
    }
marci@174
   592
    Number flowValue() { 
marci@174
   593
      Number a=0;
marci@174
   594
      OutEdgeIt e;
marci@174
   595
      for(G->/*getF*/first(e, s); G->valid(e); G->next(e)) {
marci@174
   596
	a+=flow->get(e);
marci@174
   597
      }
marci@174
   598
      return a;
marci@174
   599
    }
marci@174
   600
  };
marci@174
   601
marci@174
   602
  
marci@174
   603
//   template <typename Graph, typename Number, typename FlowMap, typename CapacityMap>
marci@174
   604
//   class MaxFlow2 {
marci@174
   605
//   public:
marci@174
   606
//     typedef typename Graph::Node Node;
marci@174
   607
//     typedef typename Graph::Edge Edge;
marci@174
   608
//     typedef typename Graph::EdgeIt EdgeIt;
marci@174
   609
//     typedef typename Graph::OutEdgeIt OutEdgeIt;
marci@174
   610
//     typedef typename Graph::InEdgeIt InEdgeIt;
marci@174
   611
//   private:
marci@174
   612
//     const Graph& G;
marci@174
   613
//     std::list<Node>& S;
marci@174
   614
//     std::list<Node>& T;
marci@174
   615
//     FlowMap& flow;
marci@174
   616
//     const CapacityMap& capacity;
marci@174
   617
//     typedef ResGraphWrapper<Graph, Number, FlowMap, CapacityMap > AugGraph;
marci@174
   618
//     typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
marci@174
   619
//     typedef typename AugGraph::Edge AugEdge;
marci@174
   620
//     typename Graph::NodeMap<bool> SMap;
marci@174
   621
//     typename Graph::NodeMap<bool> TMap;
marci@174
   622
//   public:
marci@174
   623
//     MaxFlow2(const Graph& _G, std::list<Node>& _S, std::list<Node>& _T, FlowMap& _flow, const CapacityMap& _capacity) : G(_G), S(_S), T(_T), flow(_flow), capacity(_capacity), SMap(_G), TMap(_G) { 
marci@174
   624
//       for(typename std::list<Node>::const_iterator i=S.begin(); 
marci@174
   625
// 	  i!=S.end(); ++i) { 
marci@174
   626
// 	SMap.set(*i, true); 
marci@174
   627
//       }
marci@174
   628
//       for (typename std::list<Node>::const_iterator i=T.begin(); 
marci@174
   629
// 	   i!=T.end(); ++i) { 
marci@174
   630
// 	TMap.set(*i, true); 
marci@174
   631
//       }
marci@174
   632
//     }
marci@174
   633
//     bool augment() {
marci@174
   634
//       AugGraph res_graph(G, flow, capacity);
marci@174
   635
//       bool _augment=false;
marci@174
   636
//       Node reached_t_node;
marci@174
   637
      
marci@174
   638
//       typedef typename AugGraph::NodeMap<bool> ReachedMap;
marci@174
   639
//       BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > res_bfs(res_graph);
marci@174
   640
//       for(typename std::list<Node>::const_iterator i=S.begin(); 
marci@174
   641
// 	  i!=S.end(); ++i) {
marci@174
   642
// 	res_bfs.pushAndSetReached(*i);
marci@174
   643
//       }
marci@174
   644
//       //res_bfs.pushAndSetReached(s);
marci@174
   645
	
marci@174
   646
//       typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
marci@174
   647
//       //filled up with invalid iterators
marci@174
   648
      
marci@174
   649
//       typename AugGraph::NodeMap<Number> free(res_graph);
marci@174
   650
	
marci@174
   651
//       //searching for augmenting path
marci@174
   652
//       while ( !res_bfs.finished() ) { 
marci@174
   653
// 	AugOutEdgeIt e=/*AugOutEdgeIt*/(res_bfs);
marci@174
   654
// 	if (e.valid() && res_bfs.isBNodeNewlyReached()) {
marci@174
   655
// 	  Node v=res_graph.tail(e);
marci@174
   656
// 	  Node w=res_graph.head(e);
marci@174
   657
// 	  pred.set(w, e);
marci@174
   658
// 	  if (pred.get(v).valid()) {
marci@174
   659
// 	    free.set(w, std::min(free.get(v), e.free()));
marci@174
   660
// 	  } else {
marci@174
   661
// 	    free.set(w, e.free()); 
marci@174
   662
// 	  }
marci@174
   663
// 	  if (TMap.get(res_graph.head(e))) { 
marci@174
   664
// 	    _augment=true; 
marci@174
   665
// 	    reached_t_node=res_graph.head(e);
marci@174
   666
// 	    break; 
marci@174
   667
// 	  }
marci@174
   668
// 	}
marci@174
   669
	
marci@174
   670
// 	++res_bfs;
marci@174
   671
//       } //end of searching augmenting path
marci@174
   672
marci@174
   673
//       if (_augment) {
marci@174
   674
// 	Node n=reached_t_node;
marci@174
   675
// 	Number augment_value=free.get(reached_t_node);
marci@174
   676
// 	while (pred.get(n).valid()) { 
marci@174
   677
// 	  AugEdge e=pred.get(n);
marci@174
   678
// 	  e.augment(augment_value); 
marci@174
   679
// 	  n=res_graph.tail(e);
marci@174
   680
// 	}
marci@174
   681
//       }
marci@174
   682
marci@174
   683
//       return _augment;
marci@174
   684
//     }
marci@174
   685
//     void run() {
marci@174
   686
//       while (augment()) { } 
marci@174
   687
//     }
marci@174
   688
//     Number flowValue() { 
marci@174
   689
//       Number a=0;
marci@174
   690
//       for(typename std::list<Node>::const_iterator i=S.begin(); 
marci@174
   691
// 	  i!=S.end(); ++i) { 
marci@174
   692
// 	for(OutEdgeIt e=G.template first<OutEdgeIt>(*i); e.valid(); ++e) {
marci@174
   693
// 	  a+=flow.get(e);
marci@174
   694
// 	}
marci@174
   695
// 	for(InEdgeIt e=G.template first<InEdgeIt>(*i); e.valid(); ++e) {
marci@174
   696
// 	  a-=flow.get(e);
marci@174
   697
// 	}
marci@174
   698
//       }
marci@174
   699
//       return a;
marci@174
   700
//     }
marci@174
   701
//   };
marci@174
   702
marci@174
   703
marci@174
   704
marci@174
   705
} // namespace hugo
marci@174
   706
marci@174
   707
#endif //EDMONDS_KARP_H