src/work/marci/augmenting_flow.h
changeset 1365 c280de819a73
parent 1364 ee5959aa4410
child 1366 d00b85f8be45
     1.1 --- a/src/work/marci/augmenting_flow.h	Sun Apr 17 18:57:22 2005 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,605 +0,0 @@
     1.4 -// -*- C++ -*-
     1.5 -#ifndef LEMON_AUGMENTING_FLOW_H
     1.6 -#define LEMON_AUGMENTING_FLOW_H
     1.7 -
     1.8 -#include <vector>
     1.9 -#include <iostream>
    1.10 -
    1.11 -#include <lemon/graph_wrapper.h>
    1.12 -//#include <bfs_dfs.h>
    1.13 -#include <bfs_mm.h>
    1.14 -#include <lemon/invalid.h>
    1.15 -#include <lemon/maps.h>
    1.16 -#include <demo/tight_edge_filter_map.h>
    1.17 -
    1.18 -/// \file
    1.19 -/// \brief Maximum flow algorithms.
    1.20 -/// \ingroup galgs
    1.21 -
    1.22 -namespace lemon {
    1.23 -  using lemon::marci::BfsIterator;
    1.24 -  using lemon::marci::DfsIterator;
    1.25 -
    1.26 -  /// \addtogroup galgs
    1.27 -  /// @{                                                                                                                                        
    1.28 -  /// Class for augmenting path flow algorithms.
    1.29 -
    1.30 -  /// This class provides various algorithms for finding a flow of
    1.31 -  /// maximum value in a directed graph. The \e source node, the \e
    1.32 -  /// target node, the \e capacity of the edges and the \e starting \e
    1.33 -  /// flow value of the edges should be passed to the algorithm through the
    1.34 -  /// constructor. 
    1.35 -//   /// It is possible to change these quantities using the
    1.36 -//   /// functions \ref resetSource, \ref resetTarget, \ref resetCap and
    1.37 -//   /// \ref resetFlow. Before any subsequent runs of any algorithm of
    1.38 -//   /// the class \ref resetFlow should be called. 
    1.39 -
    1.40 -  /// After running an algorithm of the class, the actual flow value 
    1.41 -  /// can be obtained by calling \ref flowValue(). The minimum
    1.42 -  /// value cut can be written into a \c node map of \c bools by
    1.43 -  /// calling \ref minCut. (\ref minMinCut and \ref maxMinCut writes
    1.44 -  /// the inclusionwise minimum and maximum of the minimum value
    1.45 -  /// cuts, resp.)                                                                                                                               
    1.46 -  ///\param Graph The directed graph type the algorithm runs on.
    1.47 -  ///\param Num The number type of the capacities and the flow values.
    1.48 -  ///\param CapMap The capacity map type.
    1.49 -  ///\param FlowMap The flow map type.                                                                                                           
    1.50 -  ///\author Marton Makai
    1.51 -  template <typename Graph, typename Num,
    1.52 -	    typename CapMap=typename Graph::template EdgeMap<Num>,
    1.53 -            typename FlowMap=typename Graph::template EdgeMap<Num> >
    1.54 -  class AugmentingFlow {
    1.55 -  protected:
    1.56 -    typedef typename Graph::Node Node;
    1.57 -    typedef typename Graph::NodeIt NodeIt;
    1.58 -    typedef typename Graph::EdgeIt EdgeIt;
    1.59 -    typedef typename Graph::OutEdgeIt OutEdgeIt;
    1.60 -    typedef typename Graph::InEdgeIt InEdgeIt;
    1.61 -
    1.62 -    const Graph* g;
    1.63 -    Node s;
    1.64 -    Node t;
    1.65 -    const CapMap* capacity;
    1.66 -    FlowMap* flow;
    1.67 -//    int n;      //the number of nodes of G
    1.68 -    typedef ResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;   
    1.69 -    //typedef ExpResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;
    1.70 -    typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
    1.71 -    typedef typename ResGW::Edge ResGWEdge;
    1.72 -    //typedef typename ResGW::template NodeMap<bool> ReachedMap;
    1.73 -    typedef typename Graph::template NodeMap<int> ReachedMap;
    1.74 -
    1.75 -    //level works as a bool map in augmenting path algorithms and is
    1.76 -    //used by bfs for storing reached information.  In preflow, it
    1.77 -    //shows the levels of nodes.     
    1.78 -    ReachedMap level;
    1.79 -
    1.80 -  public:
    1.81 -    ///Indicates the property of the starting flow.
    1.82 -
    1.83 -    ///Indicates the property of the starting flow. The meanings are as follows:
    1.84 -    ///- \c ZERO_FLOW: constant zero flow
    1.85 -    ///- \c GEN_FLOW: any flow, i.e. the sum of the in-flows equals to
    1.86 -    ///the sum of the out-flows in every node except the \e source and
    1.87 -    ///the \e target.
    1.88 -    ///- \c PRE_FLOW: any preflow, i.e. the sum of the in-flows is at 
    1.89 -    ///least the sum of the out-flows in every node except the \e source.
    1.90 -    ///- \c NO_FLOW: indicates an unspecified edge map. \ref flow will be 
    1.91 -    ///set to the constant zero flow in the beginning of the algorithm in this case.
    1.92 -    enum FlowEnum{
    1.93 -      ZERO_FLOW,
    1.94 -      GEN_FLOW,
    1.95 -      PRE_FLOW,
    1.96 -      NO_FLOW
    1.97 -    };
    1.98 -
    1.99 -    enum StatusEnum {
   1.100 -      AFTER_NOTHING,
   1.101 -      AFTER_AUGMENTING,
   1.102 -      AFTER_FAST_AUGMENTING, 
   1.103 -      AFTER_PRE_FLOW_PHASE_1,      
   1.104 -      AFTER_PRE_FLOW_PHASE_2
   1.105 -    };
   1.106 -
   1.107 -    /// Don not needle this flag only if necessary.
   1.108 -    StatusEnum status;
   1.109 -    int number_of_augmentations;
   1.110 -
   1.111 -
   1.112 -    template<typename IntMap>
   1.113 -    class TrickyReachedMap {
   1.114 -    protected:
   1.115 -      IntMap* map;
   1.116 -      int* number_of_augmentations;
   1.117 -    public:
   1.118 -      typedef Node Key;
   1.119 -      typedef bool Value;
   1.120 -      TrickyReachedMap(IntMap& _map, int& _number_of_augmentations) : 
   1.121 -	map(&_map), number_of_augmentations(&_number_of_augmentations) { }
   1.122 -      void set(const Node& n, bool b) {
   1.123 -	if (b)
   1.124 -	  map->set(n, *number_of_augmentations);
   1.125 -	else 
   1.126 -	  map->set(n, *number_of_augmentations-1);
   1.127 -      }
   1.128 -      bool operator[](const Node& n) const { 
   1.129 -	return (*map)[n]==*number_of_augmentations; 
   1.130 -      }
   1.131 -    };
   1.132 -    
   1.133 -    AugmentingFlow(const Graph& _G, Node _s, Node _t, const CapMap& _capacity,
   1.134 -		   FlowMap& _flow) :
   1.135 -      g(&_G), s(_s), t(_t), capacity(&_capacity),
   1.136 -      flow(&_flow), //n(_G.nodeNum()), 
   1.137 -      level(_G), //excess(_G,0), 
   1.138 -      status(AFTER_NOTHING), number_of_augmentations(0) { }
   1.139 -
   1.140 -    /// Starting from a flow, this method searches for an augmenting path
   1.141 -    /// according to the Edmonds-Karp algorithm
   1.142 -    /// and augments the flow on if any.
   1.143 -    /// The return value shows if the augmentation was succesful.
   1.144 -    bool augmentOnShortestPath();
   1.145 -    bool augmentOnShortestPath2();
   1.146 -
   1.147 -    /// Starting from a flow, this method searches for an augmenting blocking
   1.148 -    /// flow according to Dinits' algorithm and augments the flow on if any.
   1.149 -    /// The blocking flow is computed in a physically constructed
   1.150 -    /// residual graph of type \c Mutablegraph.
   1.151 -    /// The return value show sif the augmentation was succesful.
   1.152 -    template<typename MutableGraph> bool augmentOnBlockingFlow();
   1.153 -
   1.154 -    /// The same as \c augmentOnBlockingFlow<MutableGraph> but the
   1.155 -    /// residual graph is not constructed physically.
   1.156 -    /// The return value shows if the augmentation was succesful.
   1.157 -    bool augmentOnBlockingFlow2();
   1.158 -
   1.159 -    template<typename _CutMap>
   1.160 -    void actMinCut(_CutMap& M) const {
   1.161 -      NodeIt v;
   1.162 -      switch (status) {
   1.163 -	case AFTER_PRE_FLOW_PHASE_1:
   1.164 -//	std::cout << "AFTER_PRE_FLOW_PHASE_1" << std::endl;
   1.165 -// 	for(g->first(v); g->valid(v); g->next(v)) {
   1.166 -// 	  if (level[v] < n) {
   1.167 -// 	    M.set(v, false);
   1.168 -// 	  } else {
   1.169 -// 	    M.set(v, true);
   1.170 -// 	  }
   1.171 -// 	}
   1.172 -	break;
   1.173 -      case AFTER_PRE_FLOW_PHASE_2:
   1.174 -//	std::cout << "AFTER_PRE_FLOW_PHASE_2" << std::endl;
   1.175 -	break;
   1.176 -      case AFTER_NOTHING:
   1.177 -//	std::cout << "AFTER_NOTHING" << std::endl;
   1.178 -	minMinCut(M);
   1.179 -	break;
   1.180 -      case AFTER_AUGMENTING:
   1.181 -//	std::cout << "AFTER_AUGMENTING" << std::endl;
   1.182 -	for(g->first(v); v!=INVALID; ++v) {
   1.183 -	  if (level[v]) {
   1.184 -	    M.set(v, true);
   1.185 -	  } else {
   1.186 -	    M.set(v, false);
   1.187 -	  }
   1.188 -	}
   1.189 -	break;
   1.190 -      case AFTER_FAST_AUGMENTING:
   1.191 -//	std::cout << "AFTER_FAST_AUGMENTING" << std::endl;
   1.192 -	for(g->first(v); v!=INVALID; ++v) {
   1.193 -	  if (level[v]==number_of_augmentations) {
   1.194 -	    M.set(v, true);
   1.195 -	  } else {
   1.196 -	    M.set(v, false);
   1.197 -	  }
   1.198 -	}
   1.199 -	break;
   1.200 -      }
   1.201 -    }
   1.202 -
   1.203 -    template<typename _CutMap>
   1.204 -    void minMinCut(_CutMap& M) const {
   1.205 -      std::queue<Node> queue;
   1.206 -
   1.207 -      M.set(s,true);
   1.208 -      queue.push(s);
   1.209 -
   1.210 -      while (!queue.empty()) {
   1.211 -        Node w=queue.front();
   1.212 -	queue.pop();
   1.213 -
   1.214 -	OutEdgeIt e;
   1.215 -	for(g->first(e,w) ; e!=INVALID; ++e) {
   1.216 -	  Node v=g->target(e);
   1.217 -	  if (!M[v] && (*flow)[e] < (*capacity)[e] ) {
   1.218 -	    queue.push(v);
   1.219 -	    M.set(v, true);
   1.220 -	  }
   1.221 -	}
   1.222 -
   1.223 -	InEdgeIt f;
   1.224 -	for(g->first(f,w) ; f!=INVALID; ++f) {
   1.225 -	  Node v=g->source(f);
   1.226 -	  if (!M[v] && (*flow)[f] > 0 ) {
   1.227 -	    queue.push(v);
   1.228 -	    M.set(v, true);
   1.229 -	  }
   1.230 -	}
   1.231 -      }
   1.232 -    }
   1.233 -
   1.234 -    template<typename _CutMap>
   1.235 -    void minMinCut2(_CutMap& M) const {
   1.236 -      ResGW res_graph(*g, *capacity, *flow);
   1.237 -      BfsIterator<ResGW, _CutMap> bfs(res_graph, M);
   1.238 -      bfs.pushAndSetReached(s);
   1.239 -      while (!bfs.finished()) ++bfs;
   1.240 -    }
   1.241 -
   1.242 -    Num flowValue() const {
   1.243 -      Num a=0;
   1.244 -      for (InEdgeIt e(*g, t); e!=INVALID; ++e) a+=(*flow)[e];
   1.245 -      for (OutEdgeIt e(*g, t); e!=INVALID; ++e) a-=(*flow)[e];
   1.246 -      return a;
   1.247 -      //marci figyu: excess[t] epp ezt adja preflow 1. fazisa utan   
   1.248 -    }
   1.249 -
   1.250 -  };
   1.251 -
   1.252 -
   1.253 -
   1.254 -  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
   1.255 -  bool AugmentingFlow<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath()
   1.256 -  {
   1.257 -    ResGW res_graph(*g, *capacity, *flow);
   1.258 -    typename ResGW::ResCap res_cap(res_graph);
   1.259 -
   1.260 -    bool _augment=false;
   1.261 -
   1.262 -    //ReachedMap level(res_graph);
   1.263 -    for (typename Graph::NodeIt n(*g); n!=INVALID; ++n) level.set(n, 0);
   1.264 -    BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
   1.265 -    bfs.pushAndSetReached(s);
   1.266 -
   1.267 -    typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
   1.268 -    pred.set(s, INVALID);
   1.269 -
   1.270 -    typename ResGW::template NodeMap<Num> free(res_graph);
   1.271 -
   1.272 -    //searching for augmenting path
   1.273 -    while ( !bfs.finished() ) {
   1.274 -      ResGWEdge e=bfs;
   1.275 -      if (e!=INVALID && bfs.isBNodeNewlyReached()) {
   1.276 -	Node v=res_graph.source(e);
   1.277 -	Node w=res_graph.target(e);
   1.278 -	pred.set(w, e);
   1.279 -	if (pred[v]!=INVALID) {
   1.280 -	  free.set(w, std::min(free[v], res_cap[e]));
   1.281 -	} else {
   1.282 -	  free.set(w, res_cap[e]);
   1.283 -	}
   1.284 -	if (res_graph.target(e)==t) { _augment=true; break; }
   1.285 -      }
   1.286 -
   1.287 -      ++bfs;
   1.288 -    } //end of searching augmenting path
   1.289 -
   1.290 -    if (_augment) {
   1.291 -      Node n=t;
   1.292 -      Num augment_value=free[t];
   1.293 -      while (pred[n]!=INVALID) {
   1.294 -	ResGWEdge e=pred[n];
   1.295 -	res_graph.augment(e, augment_value);
   1.296 -	n=res_graph.source(e);
   1.297 -      }
   1.298 -    }
   1.299 -
   1.300 -    status=AFTER_AUGMENTING;
   1.301 -    return _augment;
   1.302 -  }
   1.303 -
   1.304 -  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
   1.305 -  bool AugmentingFlow<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath2()
   1.306 -  {
   1.307 -    ResGW res_graph(*g, *capacity, *flow);
   1.308 -    typename ResGW::ResCap res_cap(res_graph);
   1.309 -
   1.310 -    bool _augment=false;
   1.311 -
   1.312 -    if (status!=AFTER_FAST_AUGMENTING) {
   1.313 -      for (typename Graph::NodeIt n(*g); n!=INVALID; ++n) level.set(n, 0); 
   1.314 -      number_of_augmentations=1;
   1.315 -    } else {
   1.316 -      ++number_of_augmentations;
   1.317 -    }
   1.318 -    TrickyReachedMap<ReachedMap> 
   1.319 -      tricky_reached_map(level, number_of_augmentations);
   1.320 -    //ReachedMap level(res_graph);
   1.321 -//    FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
   1.322 -    BfsIterator<ResGW, TrickyReachedMap<ReachedMap> > 
   1.323 -      bfs(res_graph, tricky_reached_map);
   1.324 -    bfs.pushAndSetReached(s);
   1.325 -
   1.326 -    typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
   1.327 -    pred.set(s, INVALID);
   1.328 -
   1.329 -    typename ResGW::template NodeMap<Num> free(res_graph);
   1.330 -
   1.331 -    //searching for augmenting path
   1.332 -    while ( !bfs.finished() ) {
   1.333 -      ResGWEdge e=bfs;
   1.334 -      if (e!=INVALID && bfs.isBNodeNewlyReached()) {
   1.335 -	Node v=res_graph.source(e);
   1.336 -	Node w=res_graph.target(e);
   1.337 -	pred.set(w, e);
   1.338 -	if (pred[v]!=INVALID) {
   1.339 -	  free.set(w, std::min(free[v], res_cap[e]));
   1.340 -	} else {
   1.341 -	  free.set(w, res_cap[e]);
   1.342 -	}
   1.343 -	if (res_graph.target(e)==t) { _augment=true; break; }
   1.344 -      }
   1.345 -
   1.346 -      ++bfs;
   1.347 -    } //end of searching augmenting path
   1.348 -
   1.349 -    if (_augment) {
   1.350 -      Node n=t;
   1.351 -      Num augment_value=free[t];
   1.352 -      while (pred[n]!=INVALID) {
   1.353 -	ResGWEdge e=pred[n];
   1.354 -	res_graph.augment(e, augment_value);
   1.355 -	n=res_graph.source(e);
   1.356 -      }
   1.357 -    }
   1.358 -
   1.359 -    status=AFTER_FAST_AUGMENTING;
   1.360 -    return _augment;
   1.361 -  }
   1.362 -
   1.363 -
   1.364 -  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
   1.365 -  template<typename MutableGraph>
   1.366 -  bool AugmentingFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow()
   1.367 -  {
   1.368 -    typedef MutableGraph MG;
   1.369 -    bool _augment=false;
   1.370 -
   1.371 -    ResGW res_graph(*g, *capacity, *flow);
   1.372 -    typename ResGW::ResCap res_cap(res_graph);
   1.373 -
   1.374 -    //bfs for distances on the residual graph
   1.375 -    //ReachedMap level(res_graph);
   1.376 -    for (typename Graph::NodeIt n(*g); n!=INVALID; ++n) level.set(n, 0);
   1.377 -    BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
   1.378 -    bfs.pushAndSetReached(s);
   1.379 -    typename ResGW::template NodeMap<int>
   1.380 -      dist(res_graph); //filled up with 0's
   1.381 -
   1.382 -    //F will contain the physical copy of the residual graph
   1.383 -    //with the set of edges which are on shortest paths
   1.384 -    MG F;
   1.385 -    typename ResGW::template NodeMap<typename MG::Node>
   1.386 -      res_graph_to_F(res_graph);
   1.387 -    {
   1.388 -      for(typename ResGW::NodeIt n(res_graph); n!=INVALID; ++n) 
   1.389 -	res_graph_to_F.set(n, F.addNode());
   1.390 -    }
   1.391 -
   1.392 -    typename MG::Node sF=res_graph_to_F[s];
   1.393 -    typename MG::Node tF=res_graph_to_F[t];
   1.394 -    typename MG::template EdgeMap<ResGWEdge> original_edge(F);
   1.395 -    typename MG::template EdgeMap<Num> residual_capacity(F);
   1.396 -
   1.397 -    while ( !bfs.finished() ) {
   1.398 -      ResGWEdge e=bfs;
   1.399 -      if (e!=INVALID) {
   1.400 -	if (bfs.isBNodeNewlyReached()) {
   1.401 -	  dist.set(res_graph.target(e), dist[res_graph.source(e)]+1);
   1.402 -	  typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.source(e)],
   1.403 -					res_graph_to_F[res_graph.target(e)]);
   1.404 -	  //original_edge.update();
   1.405 -	  original_edge.set(f, e);
   1.406 -	  //residual_capacity.update();
   1.407 -	  residual_capacity.set(f, res_cap[e]);
   1.408 -	} else {
   1.409 -	  if (dist[res_graph.target(e)]==(dist[res_graph.source(e)]+1)) {
   1.410 -	    typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.source(e)],
   1.411 -					  res_graph_to_F[res_graph.target(e)]);
   1.412 -	    //original_edge.update();
   1.413 -	    original_edge.set(f, e);
   1.414 -	    //residual_capacity.update();
   1.415 -	    residual_capacity.set(f, res_cap[e]);
   1.416 -	  }
   1.417 -	}
   1.418 -      }
   1.419 -      ++bfs;
   1.420 -    } //computing distances from s in the residual graph
   1.421 -
   1.422 -    bool __augment=true;
   1.423 -
   1.424 -    while (__augment) {
   1.425 -      __augment=false;
   1.426 -      //computing blocking flow with dfs
   1.427 -      DfsIterator< MG, typename MG::template NodeMap<bool> > dfs(F);
   1.428 -      typename MG::template NodeMap<typename MG::Edge> pred(F);
   1.429 -      pred.set(sF, INVALID);
   1.430 -      //invalid iterators for sources
   1.431 -
   1.432 -      typename MG::template NodeMap<Num> free(F);
   1.433 -
   1.434 -      dfs.pushAndSetReached(sF);
   1.435 -      while (!dfs.finished()) {
   1.436 -	++dfs;
   1.437 -	if (typename MG::Edge(dfs)!=INVALID) {
   1.438 -	  if (dfs.isBNodeNewlyReached()) {
   1.439 -	    typename MG::Node v=F.source(dfs);
   1.440 -	    typename MG::Node w=F.target(dfs);
   1.441 -	    pred.set(w, dfs);
   1.442 -	    if (pred[v]!=INVALID) {
   1.443 -	      free.set(w, std::min(free[v], residual_capacity[dfs]));
   1.444 -	    } else {
   1.445 -	      free.set(w, residual_capacity[dfs]);
   1.446 -	    }
   1.447 -	    if (w==tF) {
   1.448 -	      __augment=true;
   1.449 -	      _augment=true;
   1.450 -	      break;
   1.451 -	    }
   1.452 -
   1.453 -	  } else {
   1.454 -	    F.erase(typename MG::Edge(dfs));
   1.455 -	  }
   1.456 -	}
   1.457 -      }
   1.458 -
   1.459 -      if (__augment) {
   1.460 -	typename MG::Node n=tF;
   1.461 -	Num augment_value=free[tF];
   1.462 -	while (pred[n]!=INVALID) {
   1.463 -	  typename MG::Edge e=pred[n];
   1.464 -	  res_graph.augment(original_edge[e], augment_value);
   1.465 -	  n=F.source(e);
   1.466 -	  if (residual_capacity[e]==augment_value)
   1.467 -	    F.erase(e);
   1.468 -	  else
   1.469 -	    residual_capacity.set(e, residual_capacity[e]-augment_value);
   1.470 -	}
   1.471 -      }
   1.472 -
   1.473 -    }
   1.474 -
   1.475 -    status=AFTER_AUGMENTING;
   1.476 -    return _augment;
   1.477 -  }
   1.478 -
   1.479 -  /// Blocking flow augmentation without constructing the layered 
   1.480 -  /// graph physically in which the blocking flow is computed.
   1.481 -  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
   1.482 -  bool AugmentingFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow2()
   1.483 -  {
   1.484 -    bool _augment=false;
   1.485 -
   1.486 -    ResGW res_graph(*g, *capacity, *flow);
   1.487 -    typename ResGW::ResCap res_cap(res_graph);
   1.488 -
   1.489 -    //Potential map, for distances from s
   1.490 -    typename ResGW::template NodeMap<int> potential(res_graph, 0);
   1.491 -    typedef ConstMap<typename ResGW::Edge, int> Const1Map; 
   1.492 -    Const1Map const_1_map(1);
   1.493 -    TightEdgeFilterMap<ResGW, typename ResGW::template NodeMap<int>,
   1.494 -      Const1Map> tight_edge_filter(res_graph, potential, const_1_map);
   1.495 -
   1.496 -    for (typename Graph::NodeIt n(*g); n!=INVALID; ++n) level.set(n, 0);
   1.497 -    BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
   1.498 -    bfs.pushAndSetReached(s);
   1.499 -
   1.500 -    //computing distances from s in the residual graph
   1.501 -    while ( !bfs.finished() ) {
   1.502 -      ResGWEdge e=bfs;
   1.503 -      if (e!=INVALID && bfs.isBNodeNewlyReached())
   1.504 -	potential.set(res_graph.target(e), potential[res_graph.source(e)]+1);
   1.505 -      ++bfs;
   1.506 -    } 
   1.507 -
   1.508 -    //Subgraph containing the edges on some shortest paths 
   1.509 -    //(i.e. tight edges)
   1.510 -    ConstMap<typename ResGW::Node, bool> true_map(true);
   1.511 -    typedef SubGraphWrapper<ResGW, ConstMap<typename ResGW::Node, bool>,
   1.512 -      TightEdgeFilterMap<ResGW, typename ResGW::template NodeMap<int>, 
   1.513 -      Const1Map> > FilterResGW;
   1.514 -    FilterResGW filter_res_graph(res_graph, true_map, tight_edge_filter);
   1.515 -
   1.516 -    //Subgraph, which is able to delete edges which are already
   1.517 -    //met by the dfs
   1.518 -    typename FilterResGW::template NodeMap<typename FilterResGW::Edge>
   1.519 -      first_out_edges(filter_res_graph);
   1.520 -    for (typename FilterResGW::NodeIt v(filter_res_graph); v!=INVALID; ++v)
   1.521 -      first_out_edges.set
   1.522 -	(v, typename FilterResGW::OutEdgeIt(filter_res_graph, v));
   1.523 -
   1.524 -    typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
   1.525 -      template NodeMap<typename FilterResGW::Edge> > ErasingResGW;
   1.526 -    ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
   1.527 -
   1.528 -    bool __augment=true;
   1.529 -
   1.530 -    while (__augment) {
   1.531 -
   1.532 -      __augment=false;
   1.533 -      //computing blocking flow with dfs
   1.534 -      DfsIterator< ErasingResGW,
   1.535 -	typename ErasingResGW::template NodeMap<bool> >
   1.536 -	dfs(erasing_res_graph);
   1.537 -      typename ErasingResGW::
   1.538 -	template NodeMap<typename ErasingResGW::Edge> pred(erasing_res_graph);
   1.539 -      pred.set(s, INVALID);
   1.540 -      //invalid iterators for sources
   1.541 -
   1.542 -      typename ErasingResGW::template NodeMap<Num>
   1.543 -	free1(erasing_res_graph);
   1.544 -
   1.545 -      dfs.pushAndSetReached
   1.546 -	/// \bug lemon 0.2
   1.547 -	(typename ErasingResGW::Node
   1.548 -	 (typename FilterResGW::Node
   1.549 -	  (typename ResGW::Node(s)
   1.550 -	   )
   1.551 -	  )
   1.552 -	 );
   1.553 -	
   1.554 -      while (!dfs.finished()) {
   1.555 -	++dfs;
   1.556 -	if (typename ErasingResGW::Edge(dfs)!=INVALID) {
   1.557 -	  if (dfs.isBNodeNewlyReached()) {
   1.558 -	    
   1.559 -	    typename ErasingResGW::Node v=erasing_res_graph.source(dfs);
   1.560 -	    typename ErasingResGW::Node w=erasing_res_graph.target(dfs);
   1.561 -
   1.562 -	    pred.set(w, typename ErasingResGW::Edge(dfs));
   1.563 -	    if (pred[v]!=INVALID) {
   1.564 -	      free1.set
   1.565 -		(w, std::min(free1[v], res_cap
   1.566 -			     [typename ErasingResGW::Edge(dfs)]));
   1.567 -	    } else {
   1.568 -	      free1.set
   1.569 -		(w, res_cap
   1.570 -		 [typename ErasingResGW::Edge(dfs)]);
   1.571 -	    }
   1.572 -
   1.573 -	    if (w==t) {
   1.574 -	      __augment=true;
   1.575 -	      _augment=true;
   1.576 -	      break;
   1.577 -	    }
   1.578 -	  } else {
   1.579 -	    erasing_res_graph.erase(dfs);
   1.580 -	  }
   1.581 -	}
   1.582 -      }
   1.583 -
   1.584 -      if (__augment) {
   1.585 -	typename ErasingResGW::Node
   1.586 -	  n=typename FilterResGW::Node(typename ResGW::Node(t));
   1.587 -	Num augment_value=free1[n];
   1.588 -	while (pred[n]!=INVALID) {
   1.589 -	  typename ErasingResGW::Edge e=pred[n];
   1.590 -	  res_graph.augment(e, augment_value);
   1.591 -	  n=erasing_res_graph.source(e);
   1.592 -	  if (res_cap[e]==0)
   1.593 -	    erasing_res_graph.erase(e);
   1.594 -	}
   1.595 -      }
   1.596 -
   1.597 -    } //while (__augment)
   1.598 -
   1.599 -    status=AFTER_AUGMENTING;
   1.600 -    return _augment;
   1.601 -  }
   1.602 -
   1.603 -
   1.604 -} //namespace lemon
   1.605 -
   1.606 -#endif //LEMON_AUGMENTING_FLOW_H
   1.607 -
   1.608 -