[Lemon-commits] kpeter: r3456 - lemon/trunk/lemon

Lemon SVN svn at lemon.cs.elte.hu
Mon Feb 18 04:30:14 CET 2008


Author: kpeter
Date: Mon Feb 18 04:30:12 2008
New Revision: 3456

Modified:
   lemon/trunk/lemon/cycle_canceling.h

Log:
Improvements in CycleCanceling.

Main changes:
- Use function parameter instead of #define commands to select negative
cycle detection method.
- Change the name of private members to start with "_".
- Change the name of function parameters not to start with "_".
- Remove unnecessary documentation for private members. 
- Doc improvements.



Modified: lemon/trunk/lemon/cycle_canceling.h
==============================================================================
--- lemon/trunk/lemon/cycle_canceling.h	(original)
+++ lemon/trunk/lemon/cycle_canceling.h	Mon Feb 18 04:30:12 2008
@@ -22,37 +22,15 @@
 /// \ingroup min_cost_flow
 ///
 /// \file
-/// \brief A cycle-canceling algorithm for finding a minimum cost flow.
+/// \brief Cycle-canceling algorithm for finding a minimum cost flow.
 
 #include <vector>
 #include <lemon/graph_adaptor.h>
-#include <lemon/circulation.h>
-
-/// \brief The used cycle-canceling method.
-#define LIMITED_CYCLE_CANCELING
-//#define MIN_MEAN_CYCLE_CANCELING
-
-#ifdef LIMITED_CYCLE_CANCELING
-  #include <lemon/bellman_ford.h>
-  // The maximum number of iterations for the first execution of the
-  // Bellman-Ford algorithm. It should be at least 2.
-  #define STARTING_LIMIT        2
-  // The iteration limit for the Bellman-Ford algorithm is multiplied by
-  // <tt>ALPHA_MUL / ALPHA_DIV</tt> in every round.
-  // <tt>ALPHA_MUL / ALPHA_DIV</tt> must be greater than 1.
-  #define ALPHA_MUL             3
-  #define ALPHA_DIV             2
-
-//#define _ONLY_ONE_CYCLE_
-//#define _NO_BACK_STEP_
-#endif
-
-#ifdef MIN_MEAN_CYCLE_CANCELING
-  #include <lemon/min_mean_cycle.h>
-  #include <lemon/path.h>
-#endif
+#include <lemon/path.h>
 
-//#define _DEBUG_ITER_
+#include <lemon/circulation.h>
+#include <lemon/bellman_ford.h>
+#include <lemon/min_mean_cycle.h>
 
 namespace lemon {
 
@@ -65,33 +43,40 @@
   /// \ref CycleCanceling implements a cycle-canceling algorithm for
   /// finding a minimum cost flow.
   ///
-  /// \param Graph The directed graph type the algorithm runs on.
-  /// \param LowerMap The type of the lower bound map.
-  /// \param CapacityMap The type of the capacity (upper bound) map.
-  /// \param CostMap The type of the cost (length) map.
-  /// \param SupplyMap The type of the supply map.
+  /// \tparam Graph The directed graph type the algorithm runs on.
+  /// \tparam LowerMap The type of the lower bound map.
+  /// \tparam CapacityMap The type of the capacity (upper bound) map.
+  /// \tparam CostMap The type of the cost (length) map.
+  /// \tparam SupplyMap The type of the supply map.
   ///
   /// \warning
-  /// - Edge capacities and costs should be non-negative integers.
-  ///   However \c CostMap::Value should be signed type.
-  /// - Supply values should be signed integers.
-  /// - \c LowerMap::Value must be convertible to
-  ///   \c CapacityMap::Value and \c CapacityMap::Value must be
-  ///   convertible to \c SupplyMap::Value.
+  /// - Edge capacities and costs should be \e non-negative \e integers.
+  /// - Supply values should be \e signed \e integers.
+  /// - \c LowerMap::Value must be convertible to \c CapacityMap::Value.
+  /// - \c CapacityMap::Value and \c SupplyMap::Value must be
+  ///   convertible to each other.
+  /// - All value types must be convertible to \c CostMap::Value, which
+  ///   must be signed type.
+  ///
+  /// \note By default the \ref BellmanFord "Bellman-Ford" algorithm is
+  /// used for negative cycle detection with limited iteration number.
+  /// However \ref CycleCanceling also provides the "Minimum Mean
+  /// Cycle-Canceling" algorithm, which is \e strongly \e polynomial,
+  /// but rather slower in practice.
+  /// To use this version of the algorithm, call \ref run() with \c true
+  /// parameter.
   ///
   /// \author Peter Kovacs
 
   template < typename Graph,
              typename LowerMap = typename Graph::template EdgeMap<int>,
-             typename CapacityMap = LowerMap,
+             typename CapacityMap = typename Graph::template EdgeMap<int>,
              typename CostMap = typename Graph::template EdgeMap<int>,
-             typename SupplyMap = typename Graph::template NodeMap
-                                  <typename CapacityMap::Value> >
+             typename SupplyMap = typename Graph::template NodeMap<int> >
   class CycleCanceling
   {
     GRAPH_TYPEDEFS(typename Graph);
 
-    typedef typename LowerMap::Value Lower;
     typedef typename CapacityMap::Value Capacity;
     typedef typename CostMap::Value Cost;
     typedef typename SupplyMap::Value Supply;
@@ -110,180 +95,200 @@
     /// The type of the flow map.
     typedef typename Graph::template EdgeMap<Capacity> FlowMap;
 
-  protected:
+  private:
 
-    /// Map adaptor class for handling residual edge costs.
-    class ResCostMap : public MapBase<ResEdge, Cost>
+    /// \brief Map adaptor class for handling residual edge costs.
+    ///
+    /// \ref ResidualCostMap is a map adaptor class for handling
+    /// residual edge costs.
+    class ResidualCostMap : public MapBase<ResEdge, Cost>
     {
     private:
 
-      const CostMap &cost_map;
+      const CostMap &_cost_map;
 
     public:
 
-      ResCostMap(const CostMap &_cost) : cost_map(_cost) {}
+      ///\e
+      ResidualCostMap(const CostMap &cost_map) : _cost_map(cost_map) {}
 
+      ///\e
       Cost operator[](const ResEdge &e) const {
-        return ResGraph::forward(e) ? cost_map[e] : -cost_map[e];
+        return ResGraph::forward(e) ? _cost_map[e] : -_cost_map[e];
       }
 
-    }; //class ResCostMap
+    }; //class ResidualCostMap
 
-  protected:
+  private:
 
-    /// The directed graph the algorithm runs on.
-    const Graph &graph;
-    /// The original lower bound map.
-    const LowerMap *lower;
-    /// The modified capacity map.
-    CapacityEdgeMap capacity;
-    /// The cost map.
-    const CostMap &cost;
-    /// The modified supply map.
-    SupplyNodeMap supply;
-    bool valid_supply;
-
-    /// The current flow.
-    FlowMap flow;
-    /// The residual graph.
-    ResGraph res_graph;
-    /// The residual cost map.
-    ResCostMap res_cost;
+    // The maximum number of iterations for the first execution of the
+    // Bellman-Ford algorithm. It should be at least 2.
+    static const int BF_FIRST_LIMIT = 2;
+    // The iteration limit for the Bellman-Ford algorithm is multiplied
+    // by BF_ALPHA in every round.
+    static const double BF_ALPHA = 1.5;
+
+  private:
+
+    // The directed graph the algorithm runs on
+    const Graph &_graph;
+    // The original lower bound map
+    const LowerMap *_lower;
+    // The modified capacity map
+    CapacityEdgeMap _capacity;
+    // The original cost map
+    const CostMap &_cost;
+    // The modified supply map
+    SupplyNodeMap _supply;
+    bool _valid_supply;
+
+    // Edge map of the current flow
+    FlowMap _flow;
+
+    // The residual graph
+    ResGraph _res_graph;
+    // The residual cost map
+    ResidualCostMap _res_cost;
 
-  public :
+  public:
 
     /// \brief General constructor of the class (with lower bounds).
     ///
     /// General constructor of the class (with lower bounds).
     ///
-    /// \param _graph The directed graph the algorithm runs on.
-    /// \param _lower The lower bounds of the edges.
-    /// \param _capacity The capacities (upper bounds) of the edges.
-    /// \param _cost The cost (length) values of the edges.
-    /// \param _supply The supply values of the nodes (signed).
-    CycleCanceling( const Graph &_graph,
-                    const LowerMap &_lower,
-                    const CapacityMap &_capacity,
-                    const CostMap &_cost,
-                    const SupplyMap &_supply ) :
-      graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
-      supply(_graph), flow(_graph, 0),
-      res_graph(_graph, capacity, flow), res_cost(cost)
+    /// \param graph The directed graph the algorithm runs on.
+    /// \param lower The lower bounds of the edges.
+    /// \param capacity The capacities (upper bounds) of the edges.
+    /// \param cost The cost (length) values of the edges.
+    /// \param supply The supply values of the nodes (signed).
+    CycleCanceling( const Graph &graph,
+                    const LowerMap &lower,
+                    const CapacityMap &capacity,
+                    const CostMap &cost,
+                    const SupplyMap &supply ) :
+      _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
+      _supply(graph), _flow(graph, 0),
+      _res_graph(graph, _capacity, _flow), _res_cost(_cost)
     {
       // Removing non-zero lower bounds
-      capacity = subMap(_capacity, _lower);
+      _capacity = subMap(capacity, lower);
       Supply sum = 0;
-      for (NodeIt n(graph); n != INVALID; ++n) {
-        Supply s = _supply[n];
-        for (InEdgeIt e(graph, n); e != INVALID; ++e)
-          s += _lower[e];
-        for (OutEdgeIt e(graph, n); e != INVALID; ++e)
-          s -= _lower[e];
-        sum += (supply[n] = s);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Supply s = supply[n];
+        for (InEdgeIt e(_graph, n); e != INVALID; ++e)
+          s += lower[e];
+        for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
+          s -= lower[e];
+        sum += (_supply[n] = s);
       }
-      valid_supply = sum == 0;
+      _valid_supply = sum == 0;
     }
 
     /// \brief General constructor of the class (without lower bounds).
     ///
     /// General constructor of the class (without lower bounds).
     ///
-    /// \param _graph The directed graph the algorithm runs on.
-    /// \param _capacity The capacities (upper bounds) of the edges.
-    /// \param _cost The cost (length) values of the edges.
-    /// \param _supply The supply values of the nodes (signed).
-    CycleCanceling( const Graph &_graph,
-                    const CapacityMap &_capacity,
-                    const CostMap &_cost,
-                    const SupplyMap &_supply ) :
-      graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
-      supply(_supply), flow(_graph, 0),
-      res_graph(_graph, capacity, flow), res_cost(cost)
+    /// \param graph The directed graph the algorithm runs on.
+    /// \param capacity The capacities (upper bounds) of the edges.
+    /// \param cost The cost (length) values of the edges.
+    /// \param supply The supply values of the nodes (signed).
+    CycleCanceling( const Graph &graph,
+                    const CapacityMap &capacity,
+                    const CostMap &cost,
+                    const SupplyMap &supply ) :
+      _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
+      _supply(supply), _flow(graph, 0),
+      _res_graph(graph, _capacity, _flow), _res_cost(_cost)
     {
       // Checking the sum of supply values
       Supply sum = 0;
-      for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n];
-      valid_supply = sum == 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
+      _valid_supply = sum == 0;
     }
 
     /// \brief Simple constructor of the class (with lower bounds).
     ///
     /// Simple constructor of the class (with lower bounds).
     ///
-    /// \param _graph The directed graph the algorithm runs on.
-    /// \param _lower The lower bounds of the edges.
-    /// \param _capacity The capacities (upper bounds) of the edges.
-    /// \param _cost The cost (length) values of the edges.
-    /// \param _s The source node.
-    /// \param _t The target node.
-    /// \param _flow_value The required amount of flow from node \c _s
-    /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t).
-    CycleCanceling( const Graph &_graph,
-                    const LowerMap &_lower,
-                    const CapacityMap &_capacity,
-                    const CostMap &_cost,
-                    Node _s, Node _t,
-                    Supply _flow_value ) :
-      graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
-      supply(_graph), flow(_graph, 0),
-      res_graph(_graph, capacity, flow), res_cost(cost)
+    /// \param graph The directed graph the algorithm runs on.
+    /// \param lower The lower bounds of the edges.
+    /// \param capacity The capacities (upper bounds) of the edges.
+    /// \param cost The cost (length) values of the edges.
+    /// \param s The source node.
+    /// \param t The target node.
+    /// \param flow_value The required amount of flow from node \c s
+    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
+    CycleCanceling( const Graph &graph,
+                    const LowerMap &lower,
+                    const CapacityMap &capacity,
+                    const CostMap &cost,
+                    Node s, Node t,
+                    Supply flow_value ) :
+      _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
+      _supply(graph), _flow(graph, 0),
+      _res_graph(graph, _capacity, _flow), _res_cost(_cost)
     {
       // Removing non-zero lower bounds
-      capacity = subMap(_capacity, _lower);
-      for (NodeIt n(graph); n != INVALID; ++n) {
-        Supply s = 0;
-        if (n == _s) s =  _flow_value;
-        if (n == _t) s = -_flow_value;
-        for (InEdgeIt e(graph, n); e != INVALID; ++e)
-          s += _lower[e];
-        for (OutEdgeIt e(graph, n); e != INVALID; ++e)
-          s -= _lower[e];
-        supply[n] = s;
+      _capacity = subMap(capacity, lower);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Supply sum = 0;
+        if (n == s) sum =  flow_value;
+        if (n == t) sum = -flow_value;
+        for (InEdgeIt e(_graph, n); e != INVALID; ++e)
+          sum += lower[e];
+        for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
+          sum -= lower[e];
+        _supply[n] = sum;
       }
-      valid_supply = true;
+      _valid_supply = true;
     }
 
     /// \brief Simple constructor of the class (without lower bounds).
     ///
     /// Simple constructor of the class (without lower bounds).
     ///
-    /// \param _graph The directed graph the algorithm runs on.
-    /// \param _capacity The capacities (upper bounds) of the edges.
-    /// \param _cost The cost (length) values of the edges.
-    /// \param _s The source node.
-    /// \param _t The target node.
-    /// \param _flow_value The required amount of flow from node \c _s
-    /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t).
-    CycleCanceling( const Graph &_graph,
-                    const CapacityMap &_capacity,
-                    const CostMap &_cost,
-                    Node _s, Node _t,
-                    Supply _flow_value ) :
-      graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
-      supply(_graph, 0), flow(_graph, 0),
-      res_graph(_graph, capacity, flow), res_cost(cost)
+    /// \param graph The directed graph the algorithm runs on.
+    /// \param capacity The capacities (upper bounds) of the edges.
+    /// \param cost The cost (length) values of the edges.
+    /// \param s The source node.
+    /// \param t The target node.
+    /// \param flow_value The required amount of flow from node \c s
+    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
+    CycleCanceling( const Graph &graph,
+                    const CapacityMap &capacity,
+                    const CostMap &cost,
+                    Node s, Node t,
+                    Supply flow_value ) :
+      _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
+      _supply(graph, 0), _flow(graph, 0),
+      _res_graph(graph, _capacity, _flow), _res_cost(_cost)
     {
-      supply[_s] =  _flow_value;
-      supply[_t] = -_flow_value;
-      valid_supply = true;
+      _supply[s] =  flow_value;
+      _supply[t] = -flow_value;
+      _valid_supply = true;
     }
 
     /// \brief Runs the algorithm.
     ///
     /// Runs the algorithm.
     ///
+    /// \param min_mean_cc Set this parameter to \c true to run the
+    /// "Minimum Mean Cycle-Canceling" algorithm, which is strongly
+    /// polynomial, but rather slower in practice.
+    ///
     /// \return \c true if a feasible flow can be found.
-    bool run() {
-      return init() && start();
+    bool run(bool min_mean_cc = false) {
+      return init() && start(min_mean_cc);
     }
 
-    /// \brief Returns a const reference to the flow map.
+    /// \brief Returns a const reference to the edge map storing the
+    /// found flow.
     ///
-    /// Returns a const reference to the flow map.
+    /// Returns a const reference to the edge map storing the found flow.
     ///
     /// \pre \ref run() must be called before using this function.
     const FlowMap& flowMap() const {
-      return flow;
+      return _flow;
     }
 
     /// \brief Returns the total cost of the found flow.
@@ -294,57 +299,54 @@
     /// \pre \ref run() must be called before using this function.
     Cost totalCost() const {
       Cost c = 0;
-      for (EdgeIt e(graph); e != INVALID; ++e)
-        c += flow[e] * cost[e];
+      for (EdgeIt e(_graph); e != INVALID; ++e)
+        c += _flow[e] * _cost[e];
       return c;
     }
 
-  protected:
+  private:
 
     /// Initializes the algorithm.
     bool init() {
-      // Checking the sum of supply values
-      Supply sum = 0;
-      for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n];
-      if (sum != 0) return false;
+      if (!_valid_supply) return false;
 
-      // Finding a feasible flow
+      // Finding a feasible flow using Circulation
       Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
                    SupplyMap >
-        circulation( graph, constMap<Edge>((Capacity)0), capacity,
-                     supply );
-      circulation.flowMap(flow);
-      return circulation.run();
+        circulation( _graph, constMap<Edge>((Capacity)0), _capacity,
+                     _supply );
+      return circulation.flowMap(_flow).run();
     }
 
-#ifdef LIMITED_CYCLE_CANCELING
-    /// \brief Executes a cycle-canceling algorithm using
-    /// \ref Bellman-Ford algorithm with limited iteration count.
+    bool start(bool min_mean_cc) {
+      if (min_mean_cc)
+        return startMinMean();
+      else
+        return start();
+    }
+
+    /// \brief Executes the algorithm using \ref BellmanFord.
+    ///
+    /// Executes the algorithm using the \ref BellmanFord
+    /// "Bellman-Ford" algorithm for negative cycle detection with
+    /// successively larger limit for the number of iterations.
     bool start() {
-      typename BellmanFord<ResGraph, ResCostMap>::PredMap pred(res_graph);
-      typename ResGraph::template NodeMap<int> visited(res_graph);
+      typename BellmanFord<ResGraph, ResidualCostMap>::PredMap pred(_res_graph);
+      typename ResGraph::template NodeMap<int> visited(_res_graph);
       std::vector<ResEdge> cycle;
-      int node_num = countNodes(graph);
+      int node_num = countNodes(_graph);
 
-#ifdef _DEBUG_ITER_
-      int cycle_num = 0;
-#endif
-      int length_bound = STARTING_LIMIT;
+      int length_bound = BF_FIRST_LIMIT;
       bool optimal = false;
       while (!optimal) {
-        BellmanFord<ResGraph, ResCostMap> bf(res_graph, res_cost);
+        BellmanFord<ResGraph, ResidualCostMap> bf(_res_graph, _res_cost);
         bf.predMap(pred);
         bf.init(0);
         int iter_num = 0;
         bool cycle_found = false;
         while (!cycle_found) {
-#ifdef _NO_BACK_STEP_
-          int curr_iter_num = length_bound <= node_num ?
-                              length_bound - iter_num : node_num - iter_num;
-#else
           int curr_iter_num = iter_num + length_bound <= node_num ?
                               length_bound : node_num - iter_num;
-#endif
           iter_num += curr_iter_num;
           int real_iter_num = curr_iter_num;
           for (int i = 0; i < curr_iter_num; ++i) {
@@ -358,18 +360,18 @@
             break;
           } else {
             // Searching for node disjoint negative cycles
-            for (ResNodeIt n(res_graph); n != INVALID; ++n)
+            for (ResNodeIt n(_res_graph); n != INVALID; ++n)
               visited[n] = 0;
             int id = 0;
-            for (ResNodeIt n(res_graph); n != INVALID; ++n) {
+            for (ResNodeIt n(_res_graph); n != INVALID; ++n) {
               if (visited[n] > 0) continue;
               visited[n] = ++id;
               ResNode u = pred[n] == INVALID ?
-                          INVALID : res_graph.source(pred[n]);
+                          INVALID : _res_graph.source(pred[n]);
               while (u != INVALID && visited[u] == 0) {
                 visited[u] = id;
                 u = pred[u] == INVALID ?
-                    INVALID : res_graph.source(pred[u]);
+                    INVALID : _res_graph.source(pred[u]);
               }
               if (u != INVALID && visited[u] == id) {
                 // Finding the negative cycle
@@ -377,62 +379,45 @@
                 cycle.clear();
                 ResEdge e = pred[u];
                 cycle.push_back(e);
-                Capacity d = res_graph.rescap(e);
-                while (res_graph.source(e) != u) {
-                  cycle.push_back(e = pred[res_graph.source(e)]);
-                  if (res_graph.rescap(e) < d)
-                    d = res_graph.rescap(e);
+                Capacity d = _res_graph.rescap(e);
+                while (_res_graph.source(e) != u) {
+                  cycle.push_back(e = pred[_res_graph.source(e)]);
+                  if (_res_graph.rescap(e) < d)
+                    d = _res_graph.rescap(e);
                 }
-#ifdef _DEBUG_ITER_
-                ++cycle_num;
-#endif
+
                 // Augmenting along the cycle
-                for (int i = 0; i < cycle.size(); ++i)
-                  res_graph.augment(cycle[i], d);
-#ifdef _ONLY_ONE_CYCLE_
-                break;
-#endif
+                for (int i = 0; i < int(cycle.size()); ++i)
+                  _res_graph.augment(cycle[i], d);
               }
             }
           }
 
           if (!cycle_found)
-            length_bound = length_bound * ALPHA_MUL / ALPHA_DIV;
+            length_bound = int(length_bound * BF_ALPHA);
         }
       }
 
-#ifdef _DEBUG_ITER_
-      std::cout << "Limited cycle-canceling algorithm finished. "
-                << "Found " << cycle_num << " negative cycles."
-                << std::endl;
-#endif
-
       // Handling non-zero lower bounds
-      if (lower) {
-        for (EdgeIt e(graph); e != INVALID; ++e)
-          flow[e] += (*lower)[e];
+      if (_lower) {
+        for (EdgeIt e(_graph); e != INVALID; ++e)
+          _flow[e] += (*_lower)[e];
       }
       return true;
     }
-#endif
 
-#ifdef MIN_MEAN_CYCLE_CANCELING
-    /// \brief Executes the minimum mean cycle-canceling algorithm
-    /// using \ref MinMeanCycle.
-    bool start() {
+    /// \brief Executes the algorithm using \ref MinMeanCycle.
+    ///
+    /// Executes the algorithm using \ref MinMeanCycle for negative
+    /// cycle detection.
+    bool startMinMean() {
       typedef Path<ResGraph> ResPath;
-      MinMeanCycle<ResGraph, ResCostMap> mmc(res_graph, res_cost);
+      MinMeanCycle<ResGraph, ResidualCostMap> mmc(_res_graph, _res_cost);
       ResPath cycle;
 
-#ifdef _DEBUG_ITER_
-      int cycle_num = 0;
-#endif
       mmc.cyclePath(cycle).init();
       if (mmc.findMinMean()) {
         while (mmc.cycleLength() < 0) {
-#ifdef _DEBUG_ITER_
-          ++cycle_num;
-#endif
           // Finding the cycle
           mmc.findCycle();
 
@@ -440,13 +425,13 @@
           // along the cycle
           Capacity delta = 0;
           for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) {
-            if (delta == 0 || res_graph.rescap(e) < delta)
-              delta = res_graph.rescap(e);
+            if (delta == 0 || _res_graph.rescap(e) < delta)
+              delta = _res_graph.rescap(e);
           }
 
           // Augmenting along the cycle
           for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e)
-            res_graph.augment(e, delta);
+            _res_graph.augment(e, delta);
 
           // Finding the minimum cycle mean for the modified residual
           // graph
@@ -455,20 +440,13 @@
         }
       }
 
-#ifdef _DEBUG_ITER_
-      std::cout << "Minimum mean cycle-canceling algorithm finished. "
-                << "Found " << cycle_num << " negative cycles."
-                << std::endl;
-#endif
-
       // Handling non-zero lower bounds
-      if (lower) {
-        for (EdgeIt e(graph); e != INVALID; ++e)
-          flow[e] += (*lower)[e];
+      if (_lower) {
+        for (EdgeIt e(_graph); e != INVALID; ++e)
+          _flow[e] += (*_lower)[e];
       }
       return true;
     }
-#endif
 
   }; //class CycleCanceling
 



More information about the Lemon-commits mailing list