src/work/edmonds_karp.h
author athos
Mon, 05 Apr 2004 14:56:32 +0000
changeset 299 54e8905344ba
parent 269 07af3069c0b8
permissions -rw-r--r--
Renaming Suurballe to minlengthpaths
marci@174
     1
// -*- c++ -*-
marci@259
     2
#ifndef HUGO_EDMONDS_KARP_H
marci@259
     3
#define HUGO_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@266
   250
  template <typename GraphWrapper, typename Number, typename FlowMap, typename CapacityMap>
marci@174
   251
  class MaxFlow {
marci@269
   252
  protected:
marci@269
   253
    typedef GraphWrapper GW;
marci@269
   254
    typedef typename GW::Node Node;
marci@269
   255
    typedef typename GW::Edge Edge;
marci@269
   256
    typedef typename GW::EdgeIt EdgeIt;
marci@269
   257
    typedef typename GW::OutEdgeIt OutEdgeIt;
marci@269
   258
    typedef typename GW::InEdgeIt InEdgeIt;
marci@266
   259
    //const Graph* G;
marci@269
   260
    GW gw;
marci@174
   261
    Node s;
marci@174
   262
    Node t;
marci@174
   263
    FlowMap* flow;
marci@174
   264
    const CapacityMap* capacity;
marci@269
   265
    typedef ResGraphWrapper<GW, Number, FlowMap, CapacityMap > ResGW;
marci@269
   266
    typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
marci@269
   267
    typedef typename ResGW::Edge ResGWEdge;
marci@269
   268
  public:
marci@174
   269
marci@269
   270
    MaxFlow(const GW& _gw, Node _s, Node _t, FlowMap& _flow, const CapacityMap& _capacity) : 
marci@266
   271
      gw(_gw), s(_s), t(_t), flow(&_flow), capacity(&_capacity) { }
marci@269
   272
marci@174
   273
    bool augmentOnShortestPath() {
marci@269
   274
      ResGW res_graph(gw, *flow, *capacity);
marci@174
   275
      bool _augment=false;
marci@174
   276
      
marci@269
   277
      typedef typename ResGW::NodeMap<bool> ReachedMap;
marci@269
   278
      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
marci@269
   279
      bfs.pushAndSetReached(s);
marci@174
   280
	
marci@269
   281
      typename ResGW::NodeMap<ResGWEdge> pred(res_graph); 
marci@269
   282
      pred.set(s, INVALID);
marci@174
   283
      
marci@269
   284
      typename ResGW::NodeMap<Number> free(res_graph);
marci@174
   285
	
marci@174
   286
      //searching for augmenting path
marci@269
   287
      while ( !bfs.finished() ) { 
marci@269
   288
	ResGWOutEdgeIt e=bfs;
marci@269
   289
	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
marci@174
   290
	  Node v=res_graph.tail(e);
marci@174
   291
	  Node w=res_graph.head(e);
marci@174
   292
	  pred.set(w, e);
marci@174
   293
	  if (res_graph.valid(pred.get(v))) {
marci@269
   294
	    free.set(w, std::min(free.get(v), res_graph.resCap(e)));
marci@174
   295
	  } else {
marci@269
   296
	    free.set(w, res_graph.resCap(e)); 
marci@174
   297
	  }
marci@174
   298
	  if (res_graph.head(e)==t) { _augment=true; break; }
marci@174
   299
	}
marci@174
   300
	
marci@269
   301
	++bfs;
marci@174
   302
      } //end of searching augmenting path
marci@174
   303
marci@174
   304
      if (_augment) {
marci@174
   305
	Node n=t;
marci@174
   306
	Number augment_value=free.get(t);
marci@174
   307
	while (res_graph.valid(pred.get(n))) { 
marci@269
   308
	  ResGWEdge e=pred.get(n);
marci@174
   309
	  res_graph.augment(e, augment_value); 
marci@174
   310
	  n=res_graph.tail(e);
marci@174
   311
	}
marci@174
   312
      }
marci@174
   313
marci@174
   314
      return _augment;
marci@174
   315
    }
marci@174
   316
marci@266
   317
    template<typename MapGraphWrapper> 
marci@263
   318
    class DistanceMap {
marci@263
   319
    protected:
marci@266
   320
      MapGraphWrapper gw;
marci@266
   321
      typename MapGraphWrapper::NodeMap<int> dist; 
marci@263
   322
    public:
marci@266
   323
      DistanceMap(MapGraphWrapper& _gw) : gw(_gw), dist(_gw, _gw.nodeNum()) { }
marci@266
   324
      void set(const typename MapGraphWrapper::Node& n, int a) { dist[n]=a; }
marci@266
   325
      int get(const typename MapGraphWrapper::Node& n) const { return dist[n]; }
marci@266
   326
      bool get(const typename MapGraphWrapper::Edge& e) const { 
marci@263
   327
	return (dist.get(gw.tail(e))<dist.get(gw.head(e))); 
marci@263
   328
      }
marci@263
   329
    };
marci@263
   330
marci@191
   331
    template<typename MutableGraph> bool augmentOnBlockingFlow() {      
marci@269
   332
      typedef MutableGraph MG;
marci@174
   333
      bool _augment=false;
marci@174
   334
marci@269
   335
      ResGW res_graph(gw, *flow, *capacity);
marci@174
   336
marci@269
   337
      typedef typename ResGW::NodeMap<bool> ReachedMap;
marci@269
   338
      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
marci@174
   339
marci@174
   340
      bfs.pushAndSetReached(s);
marci@269
   341
      //typename ResGW::NodeMap<int> dist(res_graph); //filled up with 0's
marci@269
   342
      DistanceMap<ResGW> dist(res_graph);
marci@174
   343
      while ( !bfs.finished() ) { 
marci@269
   344
	ResGWOutEdgeIt e=bfs;
marci@174
   345
	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
marci@174
   346
	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
marci@174
   347
	}
marci@174
   348
	++bfs;
marci@174
   349
      } //computing distances from s in the residual graph
marci@174
   350
marci@269
   351
      MG F;
marci@269
   352
      typedef SubGraphWrapper<ResGW, DistanceMap<ResGW> > FilterResGW;
marci@269
   353
      FilterResGW filter_res_graph(res_graph, dist);
marci@269
   354
      typename ResGW::NodeMap<typename MG::Node> res_graph_to_F(res_graph);
marci@279
   355
      {
marci@279
   356
	typename ResGW::NodeIt n;
marci@279
   357
	for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
marci@279
   358
	  res_graph_to_F.set(n, F.addNode());
marci@279
   359
	}
marci@174
   360
      }
marci@174
   361
marci@269
   362
      typename MG::Node sF=res_graph_to_F.get(s);
marci@269
   363
      typename MG::Node tF=res_graph_to_F.get(t);
marci@269
   364
      typename MG::EdgeMap<ResGWEdge> original_edge(F);
marci@269
   365
      typename MG::EdgeMap<Number> residual_capacity(F);
marci@174
   366
marci@174
   367
      //Making F to the graph containing the edges of the residual graph 
marci@174
   368
      //which are in some shortest paths
marci@279
   369
      {
marci@279
   370
	typename FilterResGW::EdgeIt e;
marci@279
   371
	for(filter_res_graph.first(e); filter_res_graph.valid(e); filter_res_graph.next(e)) {
marci@279
   372
	  //if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) {
marci@269
   373
	  typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
marci@174
   374
	  original_edge.update();
marci@174
   375
	  original_edge.set(f, e);
marci@174
   376
	  residual_capacity.update();
marci@269
   377
	  residual_capacity.set(f, res_graph.resCap(e));
marci@266
   378
	  //} 
marci@279
   379
	}
marci@174
   380
      }
marci@174
   381
marci@174
   382
      bool __augment=true;
marci@174
   383
marci@174
   384
      while (__augment) {
marci@174
   385
	__augment=false;
marci@174
   386
	//computing blocking flow with dfs
marci@269
   387
	typedef typename TrivGraphWrapper<MG>::NodeMap<bool> BlockingReachedMap;
marci@269
   388
	DfsIterator5< TrivGraphWrapper<MG>, BlockingReachedMap > dfs(F);
marci@269
   389
	typename MG::NodeMap<typename MG::Edge> pred(F);
marci@269
   390
	pred.set(sF, INVALID);
marci@174
   391
	//invalid iterators for sources
marci@174
   392
marci@269
   393
	typename MG::NodeMap<Number> free(F);
marci@174
   394
marci@174
   395
	dfs.pushAndSetReached(sF);      
marci@174
   396
	while (!dfs.finished()) {
marci@174
   397
	  ++dfs;
marci@269
   398
	  if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
marci@174
   399
	    if (dfs.isBNodeNewlyReached()) {
marci@269
   400
	      typename MG::Node v=F.aNode(dfs);
marci@269
   401
	      typename MG::Node w=F.bNode(dfs);
marci@174
   402
	      pred.set(w, dfs);
marci@174
   403
	      if (F.valid(pred.get(v))) {
marci@174
   404
		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
marci@174
   405
	      } else {
marci@174
   406
		free.set(w, residual_capacity.get(dfs)); 
marci@174
   407
	      }
marci@174
   408
	      if (w==tF) { 
marci@174
   409
		__augment=true; 
marci@174
   410
		_augment=true;
marci@174
   411
		break; 
marci@174
   412
	      }
marci@174
   413
	      
marci@174
   414
	    } else {
marci@269
   415
	      F.erase(/*typename MG::OutEdgeIt*/(dfs));
marci@174
   416
	    }
marci@174
   417
	  } 
marci@174
   418
	}
marci@174
   419
marci@174
   420
	if (__augment) {
marci@269
   421
	  typename MG::Node n=tF;
marci@174
   422
	  Number augment_value=free.get(tF);
marci@174
   423
	  while (F.valid(pred.get(n))) { 
marci@269
   424
	    typename MG::Edge e=pred.get(n);
marci@174
   425
	    res_graph.augment(original_edge.get(e), augment_value); 
marci@174
   426
	    n=F.tail(e);
marci@174
   427
	    if (residual_capacity.get(e)==augment_value) 
marci@174
   428
	      F.erase(e); 
marci@174
   429
	    else 
marci@174
   430
	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
marci@174
   431
	  }
marci@174
   432
	}
marci@174
   433
	
marci@174
   434
      }
marci@174
   435
            
marci@174
   436
      return _augment;
marci@174
   437
    }
marci@263
   438
marci@268
   439
    template<typename MutableGraph> bool augmentOnBlockingFlow1() {      
marci@269
   440
      typedef MutableGraph MG;
marci@268
   441
      bool _augment=false;
marci@193
   442
marci@269
   443
      ResGW res_graph(gw, *flow, *capacity);
marci@193
   444
marci@268
   445
      //bfs for distances on the residual graph
marci@269
   446
      typedef typename ResGW::NodeMap<bool> ReachedMap;
marci@269
   447
      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
marci@268
   448
      bfs.pushAndSetReached(s);
marci@269
   449
      typename ResGW::NodeMap<int> dist(res_graph); //filled up with 0's
marci@193
   450
marci@268
   451
      //F will contain the physical copy of the residual graph
marci@269
   452
      //with the set of edges which are on shortest paths
marci@269
   453
      MG F;
marci@269
   454
      typename ResGW::NodeMap<typename MG::Node> res_graph_to_F(res_graph);
marci@279
   455
      {
marci@279
   456
	typename ResGW::NodeIt n;
marci@279
   457
	for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
marci@279
   458
	  res_graph_to_F.set(n, F.addNode());
marci@279
   459
	}
marci@268
   460
      }
marci@269
   461
marci@269
   462
      typename MG::Node sF=res_graph_to_F.get(s);
marci@269
   463
      typename MG::Node tF=res_graph_to_F.get(t);
marci@269
   464
      typename MG::EdgeMap<ResGWEdge> original_edge(F);
marci@269
   465
      typename MG::EdgeMap<Number> residual_capacity(F);
marci@193
   466
marci@268
   467
      while ( !bfs.finished() ) { 
marci@269
   468
	ResGWOutEdgeIt e=bfs;
marci@268
   469
	if (res_graph.valid(e)) {
marci@268
   470
	  if (bfs.isBNodeNewlyReached()) {
marci@268
   471
	    dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
marci@269
   472
	    typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
marci@268
   473
	    original_edge.update();
marci@268
   474
	    original_edge.set(f, e);
marci@268
   475
	    residual_capacity.update();
marci@269
   476
	    residual_capacity.set(f, res_graph.resCap(e));
marci@268
   477
	  } else {
marci@268
   478
	    if (dist.get(res_graph.head(e))==(dist.get(res_graph.tail(e))+1)) {
marci@269
   479
	      typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
marci@268
   480
	      original_edge.update();
marci@268
   481
	      original_edge.set(f, e);
marci@268
   482
	      residual_capacity.update();
marci@269
   483
	      residual_capacity.set(f, res_graph.resCap(e));
marci@268
   484
	    }
marci@268
   485
	  }
marci@268
   486
	}
marci@268
   487
	++bfs;
marci@268
   488
      } //computing distances from s in the residual graph
marci@193
   489
marci@268
   490
      bool __augment=true;
marci@193
   491
marci@268
   492
      while (__augment) {
marci@268
   493
	__augment=false;
marci@268
   494
	//computing blocking flow with dfs
marci@269
   495
	typedef typename TrivGraphWrapper<MG>::NodeMap<bool> BlockingReachedMap;
marci@269
   496
	DfsIterator5< TrivGraphWrapper<MG>, BlockingReachedMap > dfs(F);
marci@269
   497
	typename MG::NodeMap<typename MG::Edge> pred(F);
marci@269
   498
	pred.set(sF, INVALID);
marci@268
   499
	//invalid iterators for sources
marci@193
   500
marci@269
   501
	typename MG::NodeMap<Number> free(F);
marci@193
   502
marci@268
   503
	dfs.pushAndSetReached(sF);      
marci@268
   504
	while (!dfs.finished()) {
marci@268
   505
	  ++dfs;
marci@269
   506
	  if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
marci@268
   507
	    if (dfs.isBNodeNewlyReached()) {
marci@269
   508
	      typename MG::Node v=F.aNode(dfs);
marci@269
   509
	      typename MG::Node w=F.bNode(dfs);
marci@268
   510
	      pred.set(w, dfs);
marci@268
   511
	      if (F.valid(pred.get(v))) {
marci@268
   512
		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
marci@268
   513
	      } else {
marci@268
   514
		free.set(w, residual_capacity.get(dfs)); 
marci@268
   515
	      }
marci@268
   516
	      if (w==tF) { 
marci@268
   517
		__augment=true; 
marci@268
   518
		_augment=true;
marci@268
   519
		break; 
marci@268
   520
	      }
marci@193
   521
	      
marci@268
   522
	    } else {
marci@269
   523
	      F.erase(/*typename MG::OutEdgeIt*/(dfs));
marci@268
   524
	    }
marci@268
   525
	  } 
marci@268
   526
	}
marci@193
   527
marci@268
   528
	if (__augment) {
marci@269
   529
	  typename MG::Node n=tF;
marci@268
   530
	  Number augment_value=free.get(tF);
marci@268
   531
	  while (F.valid(pred.get(n))) { 
marci@269
   532
	    typename MG::Edge e=pred.get(n);
marci@268
   533
	    res_graph.augment(original_edge.get(e), augment_value); 
marci@268
   534
	    n=F.tail(e);
marci@268
   535
	    if (residual_capacity.get(e)==augment_value) 
marci@268
   536
	      F.erase(e); 
marci@268
   537
	    else 
marci@268
   538
	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
marci@268
   539
	  }
marci@268
   540
	}
marci@193
   541
	
marci@268
   542
      }
marci@193
   543
            
marci@268
   544
      return _augment;
marci@268
   545
    }
marci@268
   546
marci@269
   547
    bool augmentOnBlockingFlow2() {
marci@269
   548
      bool _augment=false;
marci@269
   549
marci@269
   550
      ResGW res_graph(gw, *flow, *capacity);
marci@269
   551
marci@269
   552
      typedef typename ResGW::NodeMap<bool> ReachedMap;
marci@269
   553
      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
marci@269
   554
marci@269
   555
      bfs.pushAndSetReached(s);
marci@269
   556
      DistanceMap<ResGW> dist(res_graph);
marci@269
   557
      while ( !bfs.finished() ) { 
marci@269
   558
 	ResGWOutEdgeIt e=bfs;
marci@269
   559
 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
marci@269
   560
 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
marci@269
   561
 	}
marci@269
   562
	++bfs;
marci@269
   563
      } //computing distances from s in the residual graph
marci@269
   564
marci@269
   565
      //Subgraph containing the edges on some shortest paths
marci@269
   566
      typedef SubGraphWrapper<ResGW, DistanceMap<ResGW> > FilterResGW;
marci@269
   567
      FilterResGW filter_res_graph(res_graph, dist);
marci@269
   568
marci@269
   569
      //Subgraph, which is able to delete edges which are already 
marci@269
   570
      //met by the dfs
marci@269
   571
      typename FilterResGW::NodeMap<typename FilterResGW::OutEdgeIt> 
marci@269
   572
 	first_out_edges(filter_res_graph);
marci@269
   573
      typename FilterResGW::NodeIt v;
marci@269
   574
      for(filter_res_graph.first(v); filter_res_graph.valid(v); 
marci@269
   575
 	  filter_res_graph.next(v)) 
marci@269
   576
      {
marci@269
   577
 	typename FilterResGW::OutEdgeIt e;
marci@269
   578
 	filter_res_graph.first(e, v);
marci@269
   579
 	first_out_edges.set(v, e);
marci@269
   580
      }
marci@269
   581
      typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
marci@269
   582
	NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
marci@269
   583
      ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
marci@269
   584
marci@269
   585
      bool __augment=true;
marci@269
   586
marci@269
   587
      while (__augment) {
marci@269
   588
marci@269
   589
 	__augment=false;
marci@269
   590
 	//computing blocking flow with dfs
marci@269
   591
	typedef typename ErasingResGW::NodeMap<bool> BlockingReachedMap;
marci@269
   592
 	DfsIterator5< ErasingResGW, BlockingReachedMap > 
marci@269
   593
 	  dfs(erasing_res_graph);
marci@269
   594
 	typename ErasingResGW::NodeMap<typename ErasingResGW::OutEdgeIt> 
marci@269
   595
 	  pred(erasing_res_graph); 
marci@269
   596
 	pred.set(s, INVALID);
marci@269
   597
 	//invalid iterators for sources
marci@269
   598
marci@269
   599
 	typename ErasingResGW::NodeMap<Number> free(erasing_res_graph);
marci@269
   600
marci@269
   601
 	dfs.pushAndSetReached(s);
marci@269
   602
 	while (!dfs.finished()) {
marci@269
   603
 	  ++dfs;
marci@269
   604
 	  if (erasing_res_graph.valid(
marci@269
   605
 		/*typename ErasingResGW::OutEdgeIt*/(dfs))) 
marci@269
   606
 	  { 
marci@269
   607
 	    if (dfs.isBNodeNewlyReached()) {
marci@269
   608
	  
marci@269
   609
 	      typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs);
marci@269
   610
 	      typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs);
marci@269
   611
marci@269
   612
 	      pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs));
marci@269
   613
 	      if (erasing_res_graph.valid(pred.get(v))) {
marci@269
   614
 		free.set(w, std::min(free.get(v), res_graph.resCap(dfs)));
marci@269
   615
 	      } else {
marci@269
   616
 		free.set(w, res_graph.resCap(dfs)); 
marci@269
   617
 	      }
marci@269
   618
	      
marci@269
   619
 	      if (w==t) { 
marci@269
   620
 		__augment=true; 
marci@269
   621
 		_augment=true;
marci@269
   622
 		break; 
marci@269
   623
 	      }
marci@269
   624
	    } else {
marci@269
   625
	      erasing_res_graph.erase(dfs);
marci@269
   626
	    }
marci@269
   627
	  }
marci@269
   628
	}	
marci@269
   629
marci@269
   630
 	if (__augment) {
marci@269
   631
 	  typename ErasingResGW::Node n=t;
marci@269
   632
 	  Number augment_value=free.get(n);
marci@269
   633
 	  while (erasing_res_graph.valid(pred.get(n))) { 
marci@269
   634
 	    typename ErasingResGW::OutEdgeIt e=pred.get(n);
marci@269
   635
 	    res_graph.augment(e, augment_value);
marci@269
   636
 	    n=erasing_res_graph.tail(e);
marci@269
   637
 	    if (res_graph.resCap(e)==0)
marci@269
   638
 	      erasing_res_graph.erase(e);
marci@269
   639
 	  }
marci@269
   640
 	}
marci@269
   641
      
marci@269
   642
      } //while (__augment) 
marci@269
   643
            
marci@269
   644
      return _augment;
marci@269
   645
    }
marci@269
   646
marci@266
   647
//     bool augmentOnBlockingFlow2() {
marci@266
   648
//       bool _augment=false;
marci@193
   649
marci@266
   650
//       //typedef ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> EAugGraph;
marci@266
   651
//       typedef FilterGraphWrapper< ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> > EAugGraph;
marci@266
   652
//       typedef typename EAugGraph::OutEdgeIt EAugOutEdgeIt;
marci@266
   653
//       typedef typename EAugGraph::Edge EAugEdge;
marci@193
   654
marci@266
   655
//       EAugGraph res_graph(*G, *flow, *capacity);
marci@193
   656
marci@266
   657
//       //typedef typename EAugGraph::NodeMap<bool> ReachedMap;
marci@266
   658
//       BfsIterator5< 
marci@266
   659
// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>, 
marci@266
   660
// 	/*typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt,*/ 
marci@266
   661
// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<bool> > bfs(res_graph);
marci@266
   662
      
marci@266
   663
//       bfs.pushAndSetReached(s);
marci@197
   664
marci@266
   665
//       typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::
marci@266
   666
// 	NodeMap<int>& dist=res_graph.dist;
marci@197
   667
marci@266
   668
//       while ( !bfs.finished() ) {
marci@266
   669
// 	typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt e=bfs;
marci@266
   670
// 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
marci@266
   671
// 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
marci@266
   672
// 	}
marci@266
   673
// 	++bfs;	
marci@266
   674
//       } //computing distances from s in the residual graph
marci@197
   675
marci@266
   676
//       bool __augment=true;
marci@266
   677
marci@266
   678
//       while (__augment) {
marci@266
   679
marci@266
   680
// 	__augment=false;
marci@266
   681
// 	//computing blocking flow with dfs
marci@266
   682
// 	typedef typename EAugGraph::NodeMap<bool> BlockingReachedMap;
marci@266
   683
// 	DfsIterator5< EAugGraph/*, EAugOutEdgeIt*/, BlockingReachedMap > 
marci@266
   684
// 	  dfs(res_graph);
marci@266
   685
// 	typename EAugGraph::NodeMap<EAugEdge> pred(res_graph); 
marci@266
   686
// 	pred.set(s, EAugEdge(INVALID));
marci@266
   687
// 	//invalid iterators for sources
marci@266
   688
marci@266
   689
// 	typename EAugGraph::NodeMap<Number> free(res_graph);
marci@266
   690
marci@266
   691
// 	dfs.pushAndSetReached(s);
marci@266
   692
// 	while (!dfs.finished()) {
marci@266
   693
// 	  ++dfs;
marci@266
   694
// 	  if (res_graph.valid(EAugOutEdgeIt(dfs))) { 
marci@266
   695
// 	    if (dfs.isBNodeNewlyReached()) {
marci@266
   696
	  
marci@266
   697
// 	      typename EAugGraph::Node v=res_graph.aNode(dfs);
marci@266
   698
// 	      typename EAugGraph::Node w=res_graph.bNode(dfs);
marci@266
   699
marci@266
   700
// 	      pred.set(w, EAugOutEdgeIt(dfs));
marci@266
   701
// 	      if (res_graph.valid(pred.get(v))) {
marci@266
   702
// 		free.set(w, std::min(free.get(v), res_graph.free(dfs)));
marci@266
   703
// 	      } else {
marci@266
   704
// 		free.set(w, res_graph.free(dfs)); 
marci@266
   705
// 	      }
marci@266
   706
	      
marci@266
   707
// 	      if (w==t) { 
marci@266
   708
// 		__augment=true; 
marci@266
   709
// 		_augment=true;
marci@266
   710
// 		break; 
marci@266
   711
// 	      }
marci@266
   712
// 	    } else {
marci@266
   713
// 	      res_graph.erase(dfs);
marci@266
   714
// 	    }
marci@266
   715
// 	  } 
marci@266
   716
marci@266
   717
// 	}
marci@266
   718
marci@266
   719
// 	if (__augment) {
marci@266
   720
// 	  typename EAugGraph::Node n=t;
marci@266
   721
// 	  Number augment_value=free.get(t);
marci@266
   722
// 	  while (res_graph.valid(pred.get(n))) { 
marci@266
   723
// 	    EAugEdge e=pred.get(n);
marci@266
   724
// 	    res_graph.augment(e, augment_value);
marci@266
   725
// 	    n=res_graph.tail(e);
marci@266
   726
// 	    if (res_graph.free(e)==0)
marci@266
   727
// 	      res_graph.erase(e);
marci@266
   728
// 	  }
marci@266
   729
// 	}
marci@193
   730
      
marci@266
   731
//       }
marci@193
   732
            
marci@266
   733
//       return _augment;
marci@266
   734
//     }
marci@269
   735
marci@269
   736
    void run() {
marci@269
   737
      //int num_of_augmentations=0;
marci@269
   738
      while (augmentOnShortestPath()) { 
marci@269
   739
	//while (augmentOnBlockingFlow<MutableGraph>()) { 
marci@269
   740
	//std::cout << ++num_of_augmentations << " ";
marci@269
   741
	//std::cout<<std::endl;
marci@269
   742
      } 
marci@269
   743
    }
marci@269
   744
marci@269
   745
    template<typename MutableGraph> void run() {
marci@269
   746
      //int num_of_augmentations=0;
marci@269
   747
      //while (augmentOnShortestPath()) { 
marci@269
   748
	while (augmentOnBlockingFlow<MutableGraph>()) { 
marci@269
   749
	//std::cout << ++num_of_augmentations << " ";
marci@269
   750
	//std::cout<<std::endl;
marci@269
   751
      } 
marci@269
   752
    }
marci@269
   753
marci@193
   754
    Number flowValue() { 
marci@193
   755
      Number a=0;
marci@266
   756
      OutEdgeIt e;
marci@266
   757
      for(gw.first(e, s); gw.valid(e); gw.next(e)) {
marci@193
   758
	a+=flow->get(e);
marci@193
   759
      }
marci@193
   760
      return a;
marci@193
   761
    }
marci@269
   762
marci@193
   763
  };
marci@193
   764
marci@193
   765
marci@174
   766
//   template <typename Graph, typename Number, typename FlowMap, typename CapacityMap>
marci@266
   767
//   class MaxMatching {
marci@174
   768
//   public:
marci@174
   769
//     typedef typename Graph::Node Node;
marci@266
   770
//     typedef typename Graph::NodeIt NodeIt;
marci@174
   771
//     typedef typename Graph::Edge Edge;
marci@174
   772
//     typedef typename Graph::EdgeIt EdgeIt;
marci@174
   773
//     typedef typename Graph::OutEdgeIt OutEdgeIt;
marci@174
   774
//     typedef typename Graph::InEdgeIt InEdgeIt;
marci@266
   775
marci@266
   776
//     typedef typename Graph::NodeMap<bool> SMap;
marci@266
   777
//     typedef typename Graph::NodeMap<bool> TMap;
marci@174
   778
//   private:
marci@266
   779
//     const Graph* G;
marci@266
   780
//     SMap* S;
marci@266
   781
//     TMap* T;
marci@266
   782
//     //Node s;
marci@266
   783
//     //Node t;
marci@266
   784
//     FlowMap* flow;
marci@266
   785
//     const CapacityMap* capacity;
marci@174
   786
//     typedef ResGraphWrapper<Graph, Number, FlowMap, CapacityMap > AugGraph;
marci@174
   787
//     typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
marci@174
   788
//     typedef typename AugGraph::Edge AugEdge;
marci@266
   789
//     typename Graph::NodeMap<int> used; //0
marci@266
   790
marci@174
   791
//   public:
marci@266
   792
//     MaxMatching(const Graph& _G, SMap& _S, TMap& _T, FlowMap& _flow, const CapacityMap& _capacity) : 
marci@266
   793
//       G(&_G), S(&_S), T(&_T), flow(&_flow), capacity(&_capacity), used(_G) { }
marci@266
   794
//     bool augmentOnShortestPath() {
marci@266
   795
//       AugGraph res_graph(*G, *flow, *capacity);
marci@174
   796
//       bool _augment=false;
marci@174
   797
      
marci@174
   798
//       typedef typename AugGraph::NodeMap<bool> ReachedMap;
marci@269
   799
//       BfsIterator5< AugGraph, /*AugOutEdgeIt,*/ ReachedMap > bfs(res_graph);
marci@266
   800
//       typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
marci@266
   801
//       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
marci@266
   802
// 	if ((S->get(s)) && (used.get(s)<1) ) {
marci@266
   803
// 	  //Number u=0;
marci@266
   804
// 	  //for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
marci@266
   805
// 	  //u+=flow->get(e);
marci@266
   806
// 	  //if (u<1) {
marci@269
   807
// 	    bfs.pushAndSetReached(s);
marci@266
   808
// 	    pred.set(s, AugEdge(INVALID));
marci@266
   809
// 	    //}
marci@266
   810
// 	}
marci@174
   811
//       }
marci@174
   812
      
marci@174
   813
//       typename AugGraph::NodeMap<Number> free(res_graph);
marci@174
   814
	
marci@266
   815
//       Node n;
marci@174
   816
//       //searching for augmenting path
marci@269
   817
//       while ( !bfs.finished() ) { 
marci@269
   818
// 	AugOutEdgeIt e=bfs;
marci@269
   819
// 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
marci@174
   820
// 	  Node v=res_graph.tail(e);
marci@174
   821
// 	  Node w=res_graph.head(e);
marci@174
   822
// 	  pred.set(w, e);
marci@266
   823
// 	  if (res_graph.valid(pred.get(v))) {
marci@266
   824
// 	    free.set(w, std::min(free.get(v), res_graph.free(e)));
marci@174
   825
// 	  } else {
marci@266
   826
// 	    free.set(w, res_graph.free(e)); 
marci@174
   827
// 	  }
marci@266
   828
// 	  n=res_graph.head(e);
marci@266
   829
// 	  if (T->get(n) && (used.get(n)<1) ) { 
marci@266
   830
// 	    //Number u=0;
marci@266
   831
// 	    //for(InEdgeIt f=G->template first<InEdgeIt>(n); G->valid(f); G->next(f))
marci@266
   832
// 	    //u+=flow->get(f);
marci@266
   833
// 	    //if (u<1) {
marci@266
   834
// 	      _augment=true; 
marci@266
   835
// 	      break; 
marci@266
   836
// 	      //}
marci@174
   837
// 	  }
marci@174
   838
// 	}
marci@174
   839
	
marci@269
   840
// 	++bfs;
marci@174
   841
//       } //end of searching augmenting path
marci@174
   842
marci@174
   843
//       if (_augment) {
marci@266
   844
// 	//Node n=t;
marci@266
   845
// 	used.set(n, 1); //mind2 vegen jav
marci@266
   846
// 	Number augment_value=free.get(n);
marci@266
   847
// 	while (res_graph.valid(pred.get(n))) { 
marci@174
   848
// 	  AugEdge e=pred.get(n);
marci@266
   849
// 	  res_graph.augment(e, augment_value); 
marci@174
   850
// 	  n=res_graph.tail(e);
marci@174
   851
// 	}
marci@266
   852
// 	used.set(n, 1); //mind2 vegen jav
marci@174
   853
//       }
marci@174
   854
marci@174
   855
//       return _augment;
marci@174
   856
//     }
marci@266
   857
marci@266
   858
// //     template<typename MutableGraph> bool augmentOnBlockingFlow() {      
marci@266
   859
// //       bool _augment=false;
marci@266
   860
marci@266
   861
// //       AugGraph res_graph(*G, *flow, *capacity);
marci@266
   862
marci@266
   863
// //       typedef typename AugGraph::NodeMap<bool> ReachedMap;
marci@266
   864
// //       BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph);
marci@266
   865
marci@266
   866
marci@266
   867
marci@266
   868
marci@266
   869
marci@266
   870
// //       //typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
marci@266
   871
// //       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
marci@266
   872
// // 	if (S->get(s)) {
marci@266
   873
// // 	  Number u=0;
marci@266
   874
// // 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
marci@266
   875
// // 	    u+=flow->get(e);
marci@266
   876
// // 	  if (u<1) {
marci@269
   877
// // 	    bfs.pushAndSetReached(s);
marci@266
   878
// // 	    //pred.set(s, AugEdge(INVALID));
marci@266
   879
// // 	  }
marci@266
   880
// // 	}
marci@266
   881
// //       }
marci@266
   882
marci@266
   883
marci@266
   884
marci@266
   885
marci@266
   886
// //       //bfs.pushAndSetReached(s);
marci@266
   887
// //       typename AugGraph::NodeMap<int> dist(res_graph); //filled up with 0's
marci@266
   888
// //       while ( !bfs.finished() ) { 
marci@266
   889
// // 	AugOutEdgeIt e=bfs;
marci@266
   890
// // 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
marci@266
   891
// // 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
marci@266
   892
// // 	}
marci@266
   893
	
marci@266
   894
// // 	++bfs;
marci@266
   895
// //       } //computing distances from s in the residual graph
marci@266
   896
marci@266
   897
// //       MutableGraph F;
marci@266
   898
// //       typename AugGraph::NodeMap<typename MutableGraph::Node> 
marci@266
   899
// // 	res_graph_to_F(res_graph);
marci@266
   900
// //       for(typename AugGraph::NodeIt n=res_graph.template first<typename AugGraph::NodeIt>(); res_graph.valid(n); res_graph.next(n)) {
marci@266
   901
// // 	res_graph_to_F.set(n, F.addNode());
marci@266
   902
// //       }
marci@266
   903
      
marci@266
   904
// //       typename MutableGraph::Node sF=res_graph_to_F.get(s);
marci@266
   905
// //       typename MutableGraph::Node tF=res_graph_to_F.get(t);
marci@266
   906
marci@266
   907
// //       typename MutableGraph::EdgeMap<AugEdge> original_edge(F);
marci@266
   908
// //       typename MutableGraph::EdgeMap<Number> residual_capacity(F);
marci@266
   909
marci@266
   910
// //       //Making F to the graph containing the edges of the residual graph 
marci@266
   911
// //       //which are in some shortest paths
marci@266
   912
// //       for(typename AugGraph::EdgeIt e=res_graph.template first<typename AugGraph::EdgeIt>(); res_graph.valid(e); res_graph.next(e)) {
marci@266
   913
// // 	if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) {
marci@266
   914
// // 	  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@266
   915
// // 	  original_edge.update();
marci@266
   916
// // 	  original_edge.set(f, e);
marci@266
   917
// // 	  residual_capacity.update();
marci@266
   918
// // 	  residual_capacity.set(f, res_graph.free(e));
marci@266
   919
// // 	} 
marci@266
   920
// //       }
marci@266
   921
marci@266
   922
// //       bool __augment=true;
marci@266
   923
marci@266
   924
// //       while (__augment) {
marci@266
   925
// // 	__augment=false;
marci@266
   926
// // 	//computing blocking flow with dfs
marci@266
   927
// // 	typedef typename MutableGraph::NodeMap<bool> BlockingReachedMap;
marci@266
   928
// // 	DfsIterator4< MutableGraph, typename MutableGraph::OutEdgeIt, BlockingReachedMap > dfs(F);
marci@266
   929
// // 	typename MutableGraph::NodeMap<typename MutableGraph::Edge> pred(F);
marci@266
   930
// // 	pred.set(sF, typename MutableGraph::Edge(INVALID));
marci@266
   931
// // 	//invalid iterators for sources
marci@266
   932
marci@266
   933
// // 	typename MutableGraph::NodeMap<Number> free(F);
marci@266
   934
marci@266
   935
// // 	dfs.pushAndSetReached(sF);      
marci@266
   936
// // 	while (!dfs.finished()) {
marci@266
   937
// // 	  ++dfs;
marci@266
   938
// // 	  if (F.valid(typename MutableGraph::OutEdgeIt(dfs))) {
marci@266
   939
// // 	    if (dfs.isBNodeNewlyReached()) {
marci@266
   940
// // 	      typename MutableGraph::Node v=F.aNode(dfs);
marci@266
   941
// // 	      typename MutableGraph::Node w=F.bNode(dfs);
marci@266
   942
// // 	      pred.set(w, dfs);
marci@266
   943
// // 	      if (F.valid(pred.get(v))) {
marci@266
   944
// // 		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
marci@266
   945
// // 	      } else {
marci@266
   946
// // 		free.set(w, residual_capacity.get(dfs)); 
marci@266
   947
// // 	      }
marci@266
   948
// // 	      if (w==tF) { 
marci@266
   949
// // 		__augment=true; 
marci@266
   950
// // 		_augment=true;
marci@266
   951
// // 		break; 
marci@266
   952
// // 	      }
marci@266
   953
	      
marci@266
   954
// // 	    } else {
marci@266
   955
// // 	      F.erase(typename MutableGraph::OutEdgeIt(dfs));
marci@266
   956
// // 	    }
marci@266
   957
// // 	  } 
marci@266
   958
// // 	}
marci@266
   959
marci@266
   960
// // 	if (__augment) {
marci@266
   961
// // 	  typename MutableGraph::Node n=tF;
marci@266
   962
// // 	  Number augment_value=free.get(tF);
marci@266
   963
// // 	  while (F.valid(pred.get(n))) { 
marci@266
   964
// // 	    typename MutableGraph::Edge e=pred.get(n);
marci@266
   965
// // 	    res_graph.augment(original_edge.get(e), augment_value); 
marci@266
   966
// // 	    n=F.tail(e);
marci@266
   967
// // 	    if (residual_capacity.get(e)==augment_value) 
marci@266
   968
// // 	      F.erase(e); 
marci@266
   969
// // 	    else 
marci@266
   970
// // 	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
marci@266
   971
// // 	  }
marci@266
   972
// // 	}
marci@266
   973
	
marci@266
   974
// //       }
marci@266
   975
            
marci@266
   976
// //       return _augment;
marci@266
   977
// //     }
marci@266
   978
//     bool augmentOnBlockingFlow2() {
marci@266
   979
//       bool _augment=false;
marci@266
   980
marci@266
   981
//       //typedef ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> EAugGraph;
marci@266
   982
//       typedef FilterGraphWrapper< ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> > EAugGraph;
marci@266
   983
//       typedef typename EAugGraph::OutEdgeIt EAugOutEdgeIt;
marci@266
   984
//       typedef typename EAugGraph::Edge EAugEdge;
marci@266
   985
marci@266
   986
//       EAugGraph res_graph(*G, *flow, *capacity);
marci@266
   987
marci@266
   988
//       //typedef typename EAugGraph::NodeMap<bool> ReachedMap;
marci@266
   989
//       BfsIterator5< 
marci@266
   990
// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>, 
marci@266
   991
// 	/*typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt,*/ 
marci@266
   992
// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<bool> > bfs(res_graph);
marci@266
   993
marci@266
   994
marci@266
   995
//       //typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
marci@266
   996
//       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
marci@266
   997
// 	if (S->get(s)) {
marci@266
   998
// 	  Number u=0;
marci@266
   999
// 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
marci@266
  1000
// 	    u+=flow->get(e);
marci@266
  1001
// 	  if (u<1) {
marci@266
  1002
// 	    bfs.pushAndSetReached(s);
marci@266
  1003
// 	    //pred.set(s, AugEdge(INVALID));
marci@266
  1004
// 	  }
marci@266
  1005
// 	}
marci@266
  1006
//       }
marci@266
  1007
marci@266
  1008
      
marci@266
  1009
//       //bfs.pushAndSetReached(s);
marci@266
  1010
marci@266
  1011
//       typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::
marci@266
  1012
// 	NodeMap<int>& dist=res_graph.dist;
marci@266
  1013
marci@266
  1014
//       while ( !bfs.finished() ) {
marci@266
  1015
// 	typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt e=bfs;
marci@266
  1016
// 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
marci@266
  1017
// 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
marci@266
  1018
// 	}
marci@266
  1019
// 	++bfs;	
marci@266
  1020
//       } //computing distances from s in the residual graph
marci@266
  1021
marci@266
  1022
//       bool __augment=true;
marci@266
  1023
marci@266
  1024
//       while (__augment) {
marci@266
  1025
marci@266
  1026
// 	__augment=false;
marci@266
  1027
// 	//computing blocking flow with dfs
marci@266
  1028
// 	typedef typename EAugGraph::NodeMap<bool> BlockingReachedMap;
marci@266
  1029
// 	DfsIterator5< EAugGraph/*, EAugOutEdgeIt*/, BlockingReachedMap > 
marci@266
  1030
// 	  dfs(res_graph);
marci@266
  1031
// 	typename EAugGraph::NodeMap<EAugEdge> pred(res_graph, INVALID); 
marci@266
  1032
// 	//pred.set(s, EAugEdge(INVALID));
marci@266
  1033
// 	//invalid iterators for sources
marci@266
  1034
marci@266
  1035
// 	typename EAugGraph::NodeMap<Number> free(res_graph);
marci@266
  1036
marci@266
  1037
marci@266
  1038
// 	//typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
marci@266
  1039
//       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
marci@266
  1040
// 	if (S->get(s)) {
marci@266
  1041
// 	  Number u=0;
marci@266
  1042
// 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
marci@266
  1043
// 	    u+=flow->get(e);
marci@266
  1044
// 	  if (u<1) {
marci@266
  1045
// 	    dfs.pushAndSetReached(s);
marci@266
  1046
// 	    //pred.set(s, AugEdge(INVALID));
marci@266
  1047
// 	  }
marci@266
  1048
// 	}
marci@266
  1049
//       }
marci@266
  1050
marci@266
  1051
marci@266
  1052
marci@266
  1053
//       //dfs.pushAndSetReached(s);
marci@266
  1054
//       typename EAugGraph::Node n;
marci@266
  1055
// 	while (!dfs.finished()) {
marci@266
  1056
// 	  ++dfs;
marci@266
  1057
// 	  if (res_graph.valid(EAugOutEdgeIt(dfs))) { 
marci@266
  1058
// 	    if (dfs.isBNodeNewlyReached()) {
marci@266
  1059
	  
marci@266
  1060
// 	      typename EAugGraph::Node v=res_graph.aNode(dfs);
marci@266
  1061
// 	      typename EAugGraph::Node w=res_graph.bNode(dfs);
marci@266
  1062
marci@266
  1063
// 	      pred.set(w, EAugOutEdgeIt(dfs));
marci@266
  1064
// 	      if (res_graph.valid(pred.get(v))) {
marci@266
  1065
// 		free.set(w, std::min(free.get(v), res_graph.free(dfs)));
marci@266
  1066
// 	      } else {
marci@266
  1067
// 		free.set(w, res_graph.free(dfs)); 
marci@266
  1068
// 	      }
marci@266
  1069
	     
marci@266
  1070
// 	      n=w;
marci@266
  1071
// 	      if (T->get(w)) {
marci@266
  1072
// 		Number u=0;
marci@266
  1073
// 		for(InEdgeIt f=G->template first<InEdgeIt>(n); G->valid(f); G->next(f))
marci@266
  1074
// 		  u+=flow->get(f);
marci@266
  1075
// 		if (u<1) {
marci@266
  1076
// 		  __augment=true; 
marci@266
  1077
// 		  _augment=true;
marci@266
  1078
// 		  break; 
marci@266
  1079
// 		}
marci@266
  1080
// 	      }
marci@266
  1081
// 	    } else {
marci@266
  1082
// 	      res_graph.erase(dfs);
marci@266
  1083
// 	    }
marci@266
  1084
// 	  } 
marci@266
  1085
marci@266
  1086
// 	}
marci@266
  1087
marci@266
  1088
// 	if (__augment) {
marci@266
  1089
// 	  // typename EAugGraph::Node n=t;
marci@266
  1090
// 	  Number augment_value=free.get(n);
marci@266
  1091
// 	  while (res_graph.valid(pred.get(n))) { 
marci@266
  1092
// 	    EAugEdge e=pred.get(n);
marci@266
  1093
// 	    res_graph.augment(e, augment_value);
marci@266
  1094
// 	    n=res_graph.tail(e);
marci@266
  1095
// 	    if (res_graph.free(e)==0)
marci@266
  1096
// 	      res_graph.erase(e);
marci@266
  1097
// 	  }
marci@266
  1098
// 	}
marci@266
  1099
      
marci@266
  1100
//       }
marci@266
  1101
            
marci@266
  1102
//       return _augment;
marci@266
  1103
//     }
marci@174
  1104
//     void run() {
marci@266
  1105
//       //int num_of_augmentations=0;
marci@266
  1106
//       while (augmentOnShortestPath()) { 
marci@266
  1107
// 	//while (augmentOnBlockingFlow<MutableGraph>()) { 
marci@266
  1108
// 	//std::cout << ++num_of_augmentations << " ";
marci@266
  1109
// 	//std::cout<<std::endl;
marci@266
  1110
//       } 
marci@174
  1111
//     }
marci@266
  1112
// //     template<typename MutableGraph> void run() {
marci@266
  1113
// //       //int num_of_augmentations=0;
marci@266
  1114
// //       //while (augmentOnShortestPath()) { 
marci@266
  1115
// // 	while (augmentOnBlockingFlow<MutableGraph>()) { 
marci@266
  1116
// // 	//std::cout << ++num_of_augmentations << " ";
marci@266
  1117
// // 	//std::cout<<std::endl;
marci@266
  1118
// //       } 
marci@266
  1119
// //     } 
marci@174
  1120
//     Number flowValue() { 
marci@174
  1121
//       Number a=0;
marci@266
  1122
//       EdgeIt e;
marci@266
  1123
//       for(G->/*getF*/first(e); G->valid(e); G->next(e)) {
marci@266
  1124
// 	a+=flow->get(e);
marci@174
  1125
//       }
marci@174
  1126
//       return a;
marci@174
  1127
//     }
marci@174
  1128
//   };
marci@174
  1129
marci@174
  1130
marci@174
  1131
marci@266
  1132
marci@266
  1133
marci@266
  1134
  
marci@266
  1135
// //   template <typename Graph, typename Number, typename FlowMap, typename CapacityMap>
marci@266
  1136
// //   class MaxFlow2 {
marci@266
  1137
// //   public:
marci@266
  1138
// //     typedef typename Graph::Node Node;
marci@266
  1139
// //     typedef typename Graph::Edge Edge;
marci@266
  1140
// //     typedef typename Graph::EdgeIt EdgeIt;
marci@266
  1141
// //     typedef typename Graph::OutEdgeIt OutEdgeIt;
marci@266
  1142
// //     typedef typename Graph::InEdgeIt InEdgeIt;
marci@266
  1143
// //   private:
marci@266
  1144
// //     const Graph& G;
marci@266
  1145
// //     std::list<Node>& S;
marci@266
  1146
// //     std::list<Node>& T;
marci@266
  1147
// //     FlowMap& flow;
marci@266
  1148
// //     const CapacityMap& capacity;
marci@266
  1149
// //     typedef ResGraphWrapper<Graph, Number, FlowMap, CapacityMap > AugGraph;
marci@266
  1150
// //     typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
marci@266
  1151
// //     typedef typename AugGraph::Edge AugEdge;
marci@266
  1152
// //     typename Graph::NodeMap<bool> SMap;
marci@266
  1153
// //     typename Graph::NodeMap<bool> TMap;
marci@266
  1154
// //   public:
marci@266
  1155
// //     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@266
  1156
// //       for(typename std::list<Node>::const_iterator i=S.begin(); 
marci@266
  1157
// // 	  i!=S.end(); ++i) { 
marci@266
  1158
// // 	SMap.set(*i, true); 
marci@266
  1159
// //       }
marci@266
  1160
// //       for (typename std::list<Node>::const_iterator i=T.begin(); 
marci@266
  1161
// // 	   i!=T.end(); ++i) { 
marci@266
  1162
// // 	TMap.set(*i, true); 
marci@266
  1163
// //       }
marci@266
  1164
// //     }
marci@266
  1165
// //     bool augment() {
marci@266
  1166
// //       AugGraph res_graph(G, flow, capacity);
marci@266
  1167
// //       bool _augment=false;
marci@266
  1168
// //       Node reached_t_node;
marci@266
  1169
      
marci@266
  1170
// //       typedef typename AugGraph::NodeMap<bool> ReachedMap;
marci@269
  1171
// //       BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph);
marci@266
  1172
// //       for(typename std::list<Node>::const_iterator i=S.begin(); 
marci@266
  1173
// // 	  i!=S.end(); ++i) {
marci@269
  1174
// // 	bfs.pushAndSetReached(*i);
marci@266
  1175
// //       }
marci@269
  1176
// //       //bfs.pushAndSetReached(s);
marci@266
  1177
	
marci@266
  1178
// //       typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
marci@266
  1179
// //       //filled up with invalid iterators
marci@266
  1180
      
marci@266
  1181
// //       typename AugGraph::NodeMap<Number> free(res_graph);
marci@266
  1182
	
marci@266
  1183
// //       //searching for augmenting path
marci@269
  1184
// //       while ( !bfs.finished() ) { 
marci@269
  1185
// // 	AugOutEdgeIt e=/*AugOutEdgeIt*/(bfs);
marci@269
  1186
// // 	if (e.valid() && bfs.isBNodeNewlyReached()) {
marci@266
  1187
// // 	  Node v=res_graph.tail(e);
marci@266
  1188
// // 	  Node w=res_graph.head(e);
marci@266
  1189
// // 	  pred.set(w, e);
marci@266
  1190
// // 	  if (pred.get(v).valid()) {
marci@266
  1191
// // 	    free.set(w, std::min(free.get(v), e.free()));
marci@266
  1192
// // 	  } else {
marci@266
  1193
// // 	    free.set(w, e.free()); 
marci@266
  1194
// // 	  }
marci@266
  1195
// // 	  if (TMap.get(res_graph.head(e))) { 
marci@266
  1196
// // 	    _augment=true; 
marci@266
  1197
// // 	    reached_t_node=res_graph.head(e);
marci@266
  1198
// // 	    break; 
marci@266
  1199
// // 	  }
marci@266
  1200
// // 	}
marci@266
  1201
	
marci@269
  1202
// // 	++bfs;
marci@266
  1203
// //       } //end of searching augmenting path
marci@266
  1204
marci@266
  1205
// //       if (_augment) {
marci@266
  1206
// // 	Node n=reached_t_node;
marci@266
  1207
// // 	Number augment_value=free.get(reached_t_node);
marci@266
  1208
// // 	while (pred.get(n).valid()) { 
marci@266
  1209
// // 	  AugEdge e=pred.get(n);
marci@266
  1210
// // 	  e.augment(augment_value); 
marci@266
  1211
// // 	  n=res_graph.tail(e);
marci@266
  1212
// // 	}
marci@266
  1213
// //       }
marci@266
  1214
marci@266
  1215
// //       return _augment;
marci@266
  1216
// //     }
marci@266
  1217
// //     void run() {
marci@266
  1218
// //       while (augment()) { } 
marci@266
  1219
// //     }
marci@266
  1220
// //     Number flowValue() { 
marci@266
  1221
// //       Number a=0;
marci@266
  1222
// //       for(typename std::list<Node>::const_iterator i=S.begin(); 
marci@266
  1223
// // 	  i!=S.end(); ++i) { 
marci@266
  1224
// // 	for(OutEdgeIt e=G.template first<OutEdgeIt>(*i); e.valid(); ++e) {
marci@266
  1225
// // 	  a+=flow.get(e);
marci@266
  1226
// // 	}
marci@266
  1227
// // 	for(InEdgeIt e=G.template first<InEdgeIt>(*i); e.valid(); ++e) {
marci@266
  1228
// // 	  a-=flow.get(e);
marci@266
  1229
// // 	}
marci@266
  1230
// //       }
marci@266
  1231
// //       return a;
marci@266
  1232
// //     }
marci@266
  1233
// //   };
marci@266
  1234
marci@266
  1235
marci@174
  1236
} // namespace hugo
marci@174
  1237
marci@259
  1238
#endif //HUGO_EDMONDS_KARP_H