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

Lemon SVN svn at lemon.cs.elte.hu
Thu Feb 28 03:54:28 CET 2008


Author: kpeter
Date: Thu Feb 28 03:54:27 2008
New Revision: 3464

Modified:
   lemon/trunk/lemon/capacity_scaling.h
   lemon/trunk/lemon/cost_scaling.h
   lemon/trunk/lemon/cycle_canceling.h
   lemon/trunk/lemon/min_cost_flow.h
   lemon/trunk/lemon/network_simplex.h

Log:
Query improvements in the min cost flow algorithms.

- External flow and potential maps can be used.
- New query functions: flow() and potential().
- CycleCanceling also provides dual solution (node potentials).
- Doc improvements.



Modified: lemon/trunk/lemon/capacity_scaling.h
==============================================================================
--- lemon/trunk/lemon/capacity_scaling.h	(original)
+++ lemon/trunk/lemon/capacity_scaling.h	Thu Feb 28 03:54:27 2008
@@ -50,11 +50,8 @@
   /// \warning
   /// - 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.
+  /// - The value types of the maps should be convertible to each other.
+  /// - \c CostMap::Value must be signed type.
   ///
   /// \author Peter Kovacs
 
@@ -120,7 +117,7 @@
 
     public:
 
-      /// The constructor of the class.
+      /// Constructor.
       ResidualDijkstra( const Graph &graph,
                         const FlowMap &flow,
                         const CapacityEdgeMap &res_cap,
@@ -221,9 +218,11 @@
     bool _valid_supply;
 
     // Edge map of the current flow
-    FlowMap _flow;
+    FlowMap *_flow;
+    bool _local_flow;
     // Node map of the current potentials
-    PotentialMap _potential;
+    PotentialMap *_potential;
+    bool _local_potential;
 
     // The residual capacity map
     CapacityEdgeMap _res_cap;
@@ -243,13 +242,13 @@
     PredMap _pred;
     // Implementation of the Dijkstra algorithm for finding augmenting
     // shortest paths in the residual network
-    ResidualDijkstra _dijkstra;
+    ResidualDijkstra *_dijkstra;
 
-  public :
+  public:
 
-    /// \brief General constructor of the class (with lower bounds).
+    /// \brief General constructor (with lower bounds).
     ///
-    /// General constructor of the class (with lower bounds).
+    /// General constructor (with lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param lower The lower bounds of the edges.
@@ -262,9 +261,9 @@
                      const CostMap &cost,
                      const SupplyMap &supply ) :
       _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
-      _supply(graph), _flow(graph, 0), _potential(graph, 0),
-      _res_cap(graph), _excess(graph), _pred(graph),
-      _dijkstra(_graph, _flow, _res_cap, _cost, _excess, _potential, _pred)
+      _supply(graph), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false),
+      _res_cap(graph), _excess(graph), _pred(graph)
     {
       // Removing non-zero lower bounds
       _capacity = subMap(capacity, lower);
@@ -282,9 +281,9 @@
       _valid_supply = sum == 0;
     }
 
-    /// \brief General constructor of the class (without lower bounds).
+    /// \brief General constructor (without lower bounds).
     ///
-    /// General constructor of the class (without lower bounds).
+    /// General constructor (without lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param capacity The capacities (upper bounds) of the edges.
@@ -295,9 +294,9 @@
                      const CostMap &cost,
                      const SupplyMap &supply ) :
       _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
-      _supply(supply), _flow(graph, 0), _potential(graph, 0),
-      _res_cap(capacity), _excess(graph), _pred(graph),
-      _dijkstra(_graph, _flow, _res_cap, _cost, _excess, _potential, _pred)
+      _supply(supply), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false),
+      _res_cap(capacity), _excess(graph), _pred(graph)
     {
       // Checking the sum of supply values
       Supply sum = 0;
@@ -305,9 +304,9 @@
       _valid_supply = sum == 0;
     }
 
-    /// \brief Simple constructor of the class (with lower bounds).
+    /// \brief Simple constructor (with lower bounds).
     ///
-    /// Simple constructor of the class (with lower bounds).
+    /// Simple constructor (with lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param lower The lower bounds of the edges.
@@ -324,9 +323,9 @@
                      Node s, Node t,
                      Supply flow_value ) :
       _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
-      _supply(graph), _flow(graph, 0), _potential(graph, 0),
-      _res_cap(graph), _excess(graph), _pred(graph),
-      _dijkstra(_graph, _flow, _res_cap, _cost, _excess, _potential, _pred)
+      _supply(graph), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false),
+      _res_cap(graph), _excess(graph), _pred(graph)
     {
       // Removing non-zero lower bounds
       _capacity = subMap(capacity, lower);
@@ -344,9 +343,9 @@
       _valid_supply = true;
     }
 
-    /// \brief Simple constructor of the class (without lower bounds).
+    /// \brief Simple constructor (without lower bounds).
     ///
-    /// Simple constructor of the class (without lower bounds).
+    /// Simple constructor (without lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param capacity The capacities (upper bounds) of the edges.
@@ -361,15 +360,56 @@
                      Node s, Node t,
                      Supply flow_value ) :
       _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
-      _supply(graph, 0), _flow(graph, 0), _potential(graph, 0),
-      _res_cap(capacity), _excess(graph), _pred(graph),
-      _dijkstra(_graph, _flow, _res_cap, _cost, _excess, _potential, _pred)
+      _supply(graph, 0), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false),
+      _res_cap(capacity), _excess(graph), _pred(graph)
     {
       _supply[s] =  flow_value;
       _supply[t] = -flow_value;
       _valid_supply = true;
     }
 
+    /// Destructor.
+    ~CapacityScaling() {
+      if (_local_flow) delete _flow;
+      if (_local_potential) delete _potential;
+      delete _dijkstra;
+    }
+
+    /// \brief Sets the flow map.
+    ///
+    /// Sets the flow map.
+    ///
+    /// \return \c (*this)
+    CapacityScaling& flowMap(FlowMap &map) {
+      if (_local_flow) {
+        delete _flow;
+        _local_flow = false;
+      }
+      _flow = ↦
+      return *this;
+    }
+
+    /// \brief Sets the potential map.
+    ///
+    /// Sets the potential map.
+    ///
+    /// \return \c (*this)
+    CapacityScaling& potentialMap(PotentialMap &map) {
+      if (_local_potential) {
+        delete _potential;
+        _local_potential = false;
+      }
+      _potential = ↦
+      return *this;
+    }
+
+    /// \name Execution control
+    /// The only way to execute the algorithm is to call the run()
+    /// function.
+
+    /// @{
+
     /// \brief Runs the algorithm.
     ///
     /// Runs the algorithm.
@@ -384,6 +424,15 @@
       return init(scaling) && start();
     }
 
+    /// @}
+
+    /// \name Query Functions
+    /// The result of the algorithm can be obtained using these
+    /// functions.
+    /// \n run() must be called before using them.
+
+    /// @{
+
     /// \brief Returns a const reference to the edge map storing the
     /// found flow.
     ///
@@ -391,7 +440,7 @@
     ///
     /// \pre \ref run() must be called before using this function.
     const FlowMap& flowMap() const {
-      return _flow;
+      return *_flow;
     }
 
     /// \brief Returns a const reference to the node map storing the
@@ -402,7 +451,25 @@
     ///
     /// \pre \ref run() must be called before using this function.
     const PotentialMap& potentialMap() const {
-      return _potential;
+      return *_potential;
+    }
+
+    /// \brief Returns the flow on the edge.
+    ///
+    /// Returns the flow on the edge.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Capacity flow(const Edge& edge) const {
+      return (*_flow)[edge];
+    }
+
+    /// \brief Returns the potential of the node.
+    ///
+    /// Returns the potential of the node.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Cost potential(const Node& node) const {
+      return (*_potential)[node];
     }
 
     /// \brief Returns the total cost of the found flow.
@@ -414,18 +481,35 @@
     Cost totalCost() const {
       Cost c = 0;
       for (EdgeIt e(_graph); e != INVALID; ++e)
-        c += _flow[e] * _cost[e];
+        c += (*_flow)[e] * _cost[e];
       return c;
     }
 
+    /// @}
+
   private:
 
     /// Initializes the algorithm.
     bool init(bool scaling) {
       if (!_valid_supply) return false;
+
+      // Initializing maps
+      if (!_flow) {
+        _flow = new FlowMap(_graph);
+        _local_flow = true;
+      }
+      if (!_potential) {
+        _potential = new PotentialMap(_graph);
+        _local_potential = true;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
       _excess = _supply;
 
-      // Initilaizing delta value
+      _dijkstra = new ResidualDijkstra( _graph, *_flow, _res_cap, _cost,
+                                        _excess, *_potential, _pred );
+
+      // Initializing delta value
       if (scaling) {
         // With scaling
         Supply max_sup = 0, max_dem = 0;
@@ -441,6 +525,7 @@
         // Without scaling
         _delta = 1;
       }
+
       return true;
     }
 
@@ -461,17 +546,17 @@
         // Saturating all edges not satisfying the optimality condition
         for (EdgeIt e(_graph); e != INVALID; ++e) {
           Node u = _graph.source(e), v = _graph.target(e);
-          Cost c = _cost[e] + _potential[u] - _potential[v];
+          Cost c = _cost[e] + (*_potential)[u] - (*_potential)[v];
           if (c < 0 && _res_cap[e] >= _delta) {
             _excess[u] -= _res_cap[e];
             _excess[v] += _res_cap[e];
-            _flow[e] = _capacity[e];
+            (*_flow)[e] = _capacity[e];
             _res_cap[e] = 0;
           }
-          else if (c > 0 && _flow[e] >= _delta) {
-            _excess[u] += _flow[e];
-            _excess[v] -= _flow[e];
-            _flow[e] = 0;
+          else if (c > 0 && (*_flow)[e] >= _delta) {
+            _excess[u] += (*_flow)[e];
+            _excess[v] -= (*_flow)[e];
+            (*_flow)[e] = 0;
             _res_cap[e] = _capacity[e];
           }
         }
@@ -501,7 +586,7 @@
 
           // Running Dijkstra
           s = _excess_nodes[next_node];
-          if ((t = _dijkstra.run(s, _delta)) == INVALID) {
+          if ((t = _dijkstra->run(s, _delta)) == INVALID) {
             if (_delta > 1) {
               ++next_node;
               continue;
@@ -520,7 +605,7 @@
                 rc = _res_cap[e];
                 u = _graph.source(e);
               } else {
-                rc = _flow[e];
+                rc = (*_flow)[e];
                 u = _graph.target(e);
               }
               if (rc < d) d = rc;
@@ -529,11 +614,11 @@
           u = t;
           while ((e = _pred[u]) != INVALID) {
             if (u == _graph.target(e)) {
-              _flow[e] += d;
+              (*_flow)[e] += d;
               _res_cap[e] -= d;
               u = _graph.source(e);
             } else {
-              _flow[e] -= d;
+              (*_flow)[e] -= d;
               _res_cap[e] += d;
               u = _graph.target(e);
             }
@@ -552,7 +637,7 @@
       // Handling non-zero lower bounds
       if (_lower) {
         for (EdgeIt e(_graph); e != INVALID; ++e)
-          _flow[e] += (*_lower)[e];
+          (*_flow)[e] += (*_lower)[e];
       }
       return true;
     }
@@ -572,7 +657,7 @@
       {
         // Running Dijkstra
         s = _excess_nodes[next_node];
-        if ((t = _dijkstra.run(s, 1)) == INVALID)
+        if ((t = _dijkstra->run(s, 1)) == INVALID)
           return false;
 
         // Augmenting along a shortest path from s to t
@@ -585,7 +670,7 @@
             rc = _res_cap[e];
             u = _graph.source(e);
           } else {
-            rc = _flow[e];
+            rc = (*_flow)[e];
             u = _graph.target(e);
           }
           if (rc < d) d = rc;
@@ -593,11 +678,11 @@
         u = t;
         while ((e = _pred[u]) != INVALID) {
           if (u == _graph.target(e)) {
-            _flow[e] += d;
+            (*_flow)[e] += d;
             _res_cap[e] -= d;
             u = _graph.source(e);
           } else {
-            _flow[e] -= d;
+            (*_flow)[e] -= d;
             _res_cap[e] += d;
             u = _graph.target(e);
           }
@@ -609,7 +694,7 @@
       // Handling non-zero lower bounds
       if (_lower) {
         for (EdgeIt e(_graph); e != INVALID; ++e)
-          _flow[e] += (*_lower)[e];
+          (*_flow)[e] += (*_lower)[e];
       }
       return true;
     }

Modified: lemon/trunk/lemon/cost_scaling.h
==============================================================================
--- lemon/trunk/lemon/cost_scaling.h	(original)
+++ lemon/trunk/lemon/cost_scaling.h	Thu Feb 28 03:54:27 2008
@@ -54,11 +54,8 @@
   /// \warning
   /// - 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.
+  /// - The value types of the maps should be convertible to each other.
+  /// - \c CostMap::Value must be signed type.
   ///
   /// \note Edge costs are multiplied with the number of nodes during
   /// the algorithm so overflow problems may arise more easily than with
@@ -97,7 +94,7 @@
   public:
 
     /// The type of the flow map.
-    typedef CapacityEdgeMap FlowMap;
+    typedef typename Graph::template EdgeMap<Capacity> FlowMap;
     /// The type of the potential map.
     typedef typename Graph::template NodeMap<LCost> PotentialMap;
 
@@ -107,20 +104,21 @@
     ///
     /// \ref ResidualCostMap is a map adaptor class for handling
     /// residual edge costs.
-    class ResidualCostMap : public MapBase<ResEdge, LCost>
+    template <typename Map>
+    class ResidualCostMap : public MapBase<ResEdge, typename Map::Value>
     {
     private:
 
-      const LargeCostMap &_cost_map;
+      const Map &_cost_map;
 
     public:
 
       ///\e
-      ResidualCostMap(const LargeCostMap &cost_map) :
+      ResidualCostMap(const Map &cost_map) :
         _cost_map(cost_map) {}
 
       ///\e
-      LCost operator[](const ResEdge &e) const {
+      typename Map::Value operator[](const ResEdge &e) const {
         return ResGraph::forward(e) ?  _cost_map[e] : -_cost_map[e];
       }
 
@@ -160,8 +158,8 @@
     static const int ALPHA = 4;
 
     // Paramters for heuristics
-    static const int BF_HEURISTIC_EPSILON_BOUND    = 5000;
-    static const int BF_HEURISTIC_BOUND_FACTOR = 3;
+    static const int BF_HEURISTIC_EPSILON_BOUND = 5000;
+    static const int BF_HEURISTIC_BOUND_FACTOR  = 3;
 
   private:
 
@@ -180,16 +178,18 @@
     bool _valid_supply;
 
     // Edge map of the current flow
-    FlowMap _flow;
+    FlowMap *_flow;
+    bool _local_flow;
     // Node map of the current potentials
-    PotentialMap _potential;
+    PotentialMap *_potential;
+    bool _local_potential;
 
     // The residual graph
-    ResGraph _res_graph;
+    ResGraph *_res_graph;
     // The residual cost map
-    ResidualCostMap _res_cost;
+    ResidualCostMap<LargeCostMap> _res_cost;
     // The reduced cost map
-    ReducedCostMap _red_cost;
+    ReducedCostMap *_red_cost;
     // The excess map
     SupplyNodeMap _excess;
     // The epsilon parameter used for cost scaling
@@ -197,9 +197,9 @@
 
   public:
 
-    /// \brief General constructor of the class (with lower bounds).
+    /// \brief General constructor (with lower bounds).
     ///
-    /// General constructor of the class (with lower bounds).
+    /// General constructor (with lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param lower The lower bounds of the edges.
@@ -212,9 +212,9 @@
                  const CostMap &cost,
                  const SupplyMap &supply ) :
       _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost),
-      _cost(graph), _supply(graph), _flow(graph, 0), _potential(graph, 0),
-      _res_graph(graph, _capacity, _flow), _res_cost(_cost),
-      _red_cost(graph, _cost, _potential), _excess(graph, 0)
+      _cost(graph), _supply(graph), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false), _res_cost(_cost),
+      _excess(graph, 0)
     {
       // Removing non-zero lower bounds
       _capacity = subMap(capacity, lower);
@@ -231,9 +231,9 @@
       _valid_supply = sum == 0;
     }
 
-    /// \brief General constructor of the class (without lower bounds).
+    /// \brief General constructor (without lower bounds).
     ///
-    /// General constructor of the class (without lower bounds).
+    /// General constructor (without lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param capacity The capacities (upper bounds) of the edges.
@@ -244,9 +244,9 @@
                  const CostMap &cost,
                  const SupplyMap &supply ) :
       _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
-      _cost(graph), _supply(supply), _flow(graph, 0), _potential(graph, 0),
-      _res_graph(graph, _capacity, _flow), _res_cost(_cost),
-      _red_cost(graph, _cost, _potential), _excess(graph, 0)
+      _cost(graph), _supply(supply), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false), _res_cost(_cost),
+      _excess(graph, 0)
     {
       // Checking the sum of supply values
       Supply sum = 0;
@@ -254,9 +254,9 @@
       _valid_supply = sum == 0;
     }
 
-    /// \brief Simple constructor of the class (with lower bounds).
+    /// \brief Simple constructor (with lower bounds).
     ///
-    /// Simple constructor of the class (with lower bounds).
+    /// Simple constructor (with lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param lower The lower bounds of the edges.
@@ -273,9 +273,9 @@
                  Node s, Node t,
                  Supply flow_value ) :
       _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost),
-      _cost(graph), _supply(graph), _flow(graph, 0), _potential(graph, 0),
-      _res_graph(graph, _capacity, _flow), _res_cost(_cost),
-      _red_cost(graph, _cost, _potential), _excess(graph, 0)
+      _cost(graph), _supply(graph), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false), _res_cost(_cost),
+      _excess(graph, 0)
     {
       // Removing nonzero lower bounds
       _capacity = subMap(capacity, lower);
@@ -292,9 +292,9 @@
       _valid_supply = true;
     }
 
-    /// \brief Simple constructor of the class (without lower bounds).
+    /// \brief Simple constructor (without lower bounds).
     ///
-    /// Simple constructor of the class (without lower bounds).
+    /// Simple constructor (without lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param capacity The capacities (upper bounds) of the edges.
@@ -309,24 +309,75 @@
                  Node s, Node t,
                  Supply flow_value ) :
       _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
-      _cost(graph), _supply(graph, 0), _flow(graph, 0), _potential(graph, 0),
-      _res_graph(graph, _capacity, _flow), _res_cost(_cost),
-      _red_cost(graph, _cost, _potential), _excess(graph, 0)
+      _cost(graph), _supply(graph, 0), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false), _res_cost(_cost),
+      _excess(graph, 0)
     {
       _supply[s] =  flow_value;
       _supply[t] = -flow_value;
       _valid_supply = true;
     }
 
+    /// Destructor.
+    ~CostScaling() {
+      if (_local_flow) delete _flow;
+      if (_local_potential) delete _potential;
+      delete _res_graph;
+      delete _red_cost;
+    }
+
+    /// \brief Sets the flow map.
+    ///
+    /// Sets the flow map.
+    ///
+    /// \return \c (*this)
+    CostScaling& flowMap(FlowMap &map) {
+      if (_local_flow) {
+        delete _flow;
+        _local_flow = false;
+      }
+      _flow = ↦
+      return *this;
+    }
+
+    /// \brief Sets the potential map.
+    ///
+    /// Sets the potential map.
+    ///
+    /// \return \c (*this)
+    CostScaling& potentialMap(PotentialMap &map) {
+      if (_local_potential) {
+        delete _potential;
+        _local_potential = false;
+      }
+      _potential = ↦
+      return *this;
+    }
+
+    /// \name Execution control
+    /// The only way to execute the algorithm is to call the run()
+    /// function.
+
+    /// @{
+
     /// \brief Runs the algorithm.
     ///
     /// Runs the algorithm.
     ///
     /// \return \c true if a feasible flow can be found.
     bool run() {
-      init() && start();
+      return init() && start();
     }
 
+    /// @}
+
+    /// \name Query Functions
+    /// The result of the algorithm can be obtained using these
+    /// functions.
+    /// \n run() must be called before using them.
+
+    /// @{
+
     /// \brief Returns a const reference to the edge map storing the
     /// found flow.
     ///
@@ -334,7 +385,7 @@
     ///
     /// \pre \ref run() must be called before using this function.
     const FlowMap& flowMap() const {
-      return _flow;
+      return *_flow;
     }
 
     /// \brief Returns a const reference to the node map storing the
@@ -345,7 +396,25 @@
     ///
     /// \pre \ref run() must be called before using this function.
     const PotentialMap& potentialMap() const {
-      return _potential;
+      return *_potential;
+    }
+
+    /// \brief Returns the flow on the edge.
+    ///
+    /// Returns the flow on the edge.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Capacity flow(const Edge& edge) const {
+      return (*_flow)[edge];
+    }
+
+    /// \brief Returns the potential of the node.
+    ///
+    /// Returns the potential of the node.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Cost potential(const Node& node) const {
+      return (*_potential)[node];
     }
 
     /// \brief Returns the total cost of the found flow.
@@ -357,16 +426,31 @@
     Cost totalCost() const {
       Cost c = 0;
       for (EdgeIt e(_graph); e != INVALID; ++e)
-        c += _flow[e] * _orig_cost[e];
+        c += (*_flow)[e] * _orig_cost[e];
       return c;
     }
 
+    /// @}
+
   private:
 
     /// Initializes the algorithm.
     bool init() {
       if (!_valid_supply) return false;
 
+      // Initializing flow and potential maps
+      if (!_flow) {
+        _flow = new FlowMap(_graph);
+        _local_flow = true;
+      }
+      if (!_potential) {
+        _potential = new PotentialMap(_graph);
+        _local_potential = true;
+      }
+
+      _red_cost = new ReducedCostMap(_graph, _cost, *_potential);
+      _res_graph = new ResGraph(_graph, _capacity, *_flow);
+
       // Initializing the scaled cost map and the epsilon parameter
       Cost max_cost = 0;
       int node_num = countNodes(_graph);
@@ -379,9 +463,9 @@
       // Finding a feasible flow using Circulation
       Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
                    SupplyMap >
-        circulation( _graph, constMap<Edge>((Capacity)0), _capacity,
+        circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
                      _supply );
-      return circulation.flowMap(_flow).run();
+      return circulation.flowMap(*_flow).run();
     }
 
 
@@ -397,9 +481,9 @@
         // Performing price refinement heuristic using Bellman-Ford
         // algorithm
         if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
-          typedef ShiftMap<ResidualCostMap> ShiftCostMap;
+          typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
           ShiftCostMap shift_cost(_res_cost, _epsilon);
-          BellmanFord<ResGraph, ShiftCostMap> bf(_res_graph, shift_cost);
+          BellmanFord<ResGraph, ShiftCostMap> bf(*_res_graph, shift_cost);
           bf.init(0);
           bool done = false;
           int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
@@ -407,7 +491,7 @@
             done = bf.processNextWeakRound();
           if (done) {
             for (NodeIt n(_graph); n != INVALID; ++n)
-              _potential[n] = bf.dist(n);
+              (*_potential)[n] = bf.dist(n);
             continue;
           }
         }
@@ -415,16 +499,16 @@
         // Saturating edges not satisfying the optimality condition
         Capacity delta;
         for (EdgeIt e(_graph); e != INVALID; ++e) {
-          if (_capacity[e] - _flow[e] > 0 && _red_cost[e] < 0) {
-            delta = _capacity[e] - _flow[e];
+          if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
+            delta = _capacity[e] - (*_flow)[e];
             _excess[_graph.source(e)] -= delta;
             _excess[_graph.target(e)] += delta;
-            _flow[e] = _capacity[e];
+            (*_flow)[e] = _capacity[e];
           }
-          if (_flow[e] > 0 && -_red_cost[e] < 0) {
-            _excess[_graph.target(e)] -= _flow[e];
-            _excess[_graph.source(e)] += _flow[e];
-            _flow[e] = 0;
+          if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
+            _excess[_graph.target(e)] -= (*_flow)[e];
+            _excess[_graph.source(e)] += (*_flow)[e];
+            (*_flow)[e] = 0;
           }
         }
 
@@ -440,26 +524,26 @@
           // Performing push operations if there are admissible edges
           if (_excess[n] > 0) {
             for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
-              if (_capacity[e] - _flow[e] > 0 && _red_cost[e] < 0) {
-                delta = _capacity[e] - _flow[e] <= _excess[n] ?
-                        _capacity[e] - _flow[e] : _excess[n];
+              if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
+                delta = _capacity[e] - (*_flow)[e] <= _excess[n] ?
+                        _capacity[e] - (*_flow)[e] : _excess[n];
                 t = _graph.target(e);
 
                 // Push-look-ahead heuristic
                 Capacity ahead = -_excess[t];
                 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
-                  if (_capacity[oe] - _flow[oe] > 0 && _red_cost[oe] < 0)
-                    ahead += _capacity[oe] - _flow[oe];
+                  if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
+                    ahead += _capacity[oe] - (*_flow)[oe];
                 }
                 for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) {
-                  if (_flow[ie] > 0 && -_red_cost[ie] < 0)
-                    ahead += _flow[ie];
+                  if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
+                    ahead += (*_flow)[ie];
                 }
                 if (ahead < 0) ahead = 0;
 
                 // Pushing flow along the edge
                 if (ahead < delta) {
-                  _flow[e] += ahead;
+                  (*_flow)[e] += ahead;
                   _excess[n] -= ahead;
                   _excess[t] += ahead;
                   active_nodes.push_front(t);
@@ -467,7 +551,7 @@
                   relabel_enabled = false;
                   break;
                 } else {
-                  _flow[e] += delta;
+                  (*_flow)[e] += delta;
                   _excess[n] -= delta;
                   _excess[t] += delta;
                   if (_excess[t] > 0 && _excess[t] <= delta)
@@ -481,25 +565,25 @@
 
           if (_excess[n] > 0) {
             for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
-              if (_flow[e] > 0 && -_red_cost[e] < 0) {
-                delta = _flow[e] <= _excess[n] ? _flow[e] : _excess[n];
+              if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
+                delta = (*_flow)[e] <= _excess[n] ? (*_flow)[e] : _excess[n];
                 t = _graph.source(e);
 
                 // Push-look-ahead heuristic
                 Capacity ahead = -_excess[t];
                 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
-                  if (_capacity[oe] - _flow[oe] > 0 && _red_cost[oe] < 0)
-                    ahead += _capacity[oe] - _flow[oe];
+                  if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
+                    ahead += _capacity[oe] - (*_flow)[oe];
                 }
                 for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) {
-                  if (_flow[ie] > 0 && -_red_cost[ie] < 0)
-                    ahead += _flow[ie];
+                  if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
+                    ahead += (*_flow)[ie];
                 }
                 if (ahead < 0) ahead = 0;
 
                 // Pushing flow along the edge
                 if (ahead < delta) {
-                  _flow[e] -= ahead;
+                  (*_flow)[e] -= ahead;
                   _excess[n] -= ahead;
                   _excess[t] += ahead;
                   active_nodes.push_front(t);
@@ -507,7 +591,7 @@
                   relabel_enabled = false;
                   break;
                 } else {
-                  _flow[e] -= delta;
+                  (*_flow)[e] -= delta;
                   _excess[n] -= delta;
                   _excess[t] += delta;
                   if (_excess[t] > 0 && _excess[t] <= delta)
@@ -523,15 +607,15 @@
             // Performing relabel operation if the node is still active
             LCost min_red_cost = std::numeric_limits<LCost>::max();
             for (OutEdgeIt oe(_graph, n); oe != INVALID; ++oe) {
-              if ( _capacity[oe] - _flow[oe] > 0 &&
-                   _red_cost[oe] < min_red_cost )
-                min_red_cost = _red_cost[oe];
+              if ( _capacity[oe] - (*_flow)[oe] > 0 &&
+                   (*_red_cost)[oe] < min_red_cost )
+                min_red_cost = (*_red_cost)[oe];
             }
             for (InEdgeIt ie(_graph, n); ie != INVALID; ++ie) {
-              if (_flow[ie] > 0 && -_red_cost[ie] < min_red_cost)
-                min_red_cost = -_red_cost[ie];
+              if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
+                min_red_cost = -(*_red_cost)[ie];
             }
-            _potential[n] -= min_red_cost + _epsilon;
+            (*_potential)[n] -= min_red_cost + _epsilon;
             hyper[n] = false;
           }
 
@@ -544,10 +628,18 @@
         }
       }
 
+      // Computing node potentials for the original costs
+      ResidualCostMap<CostMap> res_cost(_orig_cost);
+      BellmanFord< ResGraph, ResidualCostMap<CostMap> >
+        bf(*_res_graph, res_cost);
+      bf.init(0); bf.start();
+      for (NodeIt n(_graph); n != INVALID; ++n)
+        (*_potential)[n] = bf.dist(n);
+
       // Handling non-zero lower bounds
       if (_lower) {
         for (EdgeIt e(_graph); e != INVALID; ++e)
-          _flow[e] += (*_lower)[e];
+          (*_flow)[e] += (*_lower)[e];
       }
       return true;
     }

Modified: lemon/trunk/lemon/cycle_canceling.h
==============================================================================
--- lemon/trunk/lemon/cycle_canceling.h	(original)
+++ lemon/trunk/lemon/cycle_canceling.h	Thu Feb 28 03:54:27 2008
@@ -52,11 +52,8 @@
   /// \warning
   /// - 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.
+  /// - The value types of the maps should be convertible to each other.
+  /// - \c CostMap::Value must be signed type.
   ///
   /// \note By default the \ref BellmanFord "Bellman-Ford" algorithm is
   /// used for negative cycle detection with limited iteration number.
@@ -94,6 +91,8 @@
 
     /// The type of the flow map.
     typedef typename Graph::template EdgeMap<Capacity> FlowMap;
+    /// The type of the potential map.
+    typedef typename Graph::template NodeMap<Cost> PotentialMap;
 
   private:
 
@@ -143,18 +142,22 @@
     bool _valid_supply;
 
     // Edge map of the current flow
-    FlowMap _flow;
+    FlowMap *_flow;
+    bool _local_flow;
+    // Node map of the current potentials
+    PotentialMap *_potential;
+    bool _local_potential;
 
     // The residual graph
-    ResGraph _res_graph;
+    ResGraph *_res_graph;
     // The residual cost map
     ResidualCostMap _res_cost;
 
   public:
 
-    /// \brief General constructor of the class (with lower bounds).
+    /// \brief General constructor (with lower bounds).
     ///
-    /// General constructor of the class (with lower bounds).
+    /// General constructor (with lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param lower The lower bounds of the edges.
@@ -167,8 +170,8 @@
                     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)
+      _supply(graph), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false), _res_cost(_cost)
     {
       // Removing non-zero lower bounds
       _capacity = subMap(capacity, lower);
@@ -184,9 +187,9 @@
       _valid_supply = sum == 0;
     }
 
-    /// \brief General constructor of the class (without lower bounds).
+    /// \brief General constructor (without lower bounds).
     ///
-    /// General constructor of the class (without lower bounds).
+    /// General constructor (without lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param capacity The capacities (upper bounds) of the edges.
@@ -197,8 +200,8 @@
                     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)
+      _supply(supply), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false), _res_cost(_cost)
     {
       // Checking the sum of supply values
       Supply sum = 0;
@@ -206,9 +209,9 @@
       _valid_supply = sum == 0;
     }
 
-    /// \brief Simple constructor of the class (with lower bounds).
+    /// \brief Simple constructor (with lower bounds).
     ///
-    /// Simple constructor of the class (with lower bounds).
+    /// Simple constructor (with lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param lower The lower bounds of the edges.
@@ -225,8 +228,8 @@
                     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)
+      _supply(graph), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false), _res_cost(_cost)
     {
       // Removing non-zero lower bounds
       _capacity = subMap(capacity, lower);
@@ -243,9 +246,9 @@
       _valid_supply = true;
     }
 
-    /// \brief Simple constructor of the class (without lower bounds).
+    /// \brief Simple constructor (without lower bounds).
     ///
-    /// Simple constructor of the class (without lower bounds).
+    /// Simple constructor (without lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param capacity The capacities (upper bounds) of the edges.
@@ -260,14 +263,55 @@
                     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(graph, 0), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false), _res_cost(_cost)
     {
       _supply[s] =  flow_value;
       _supply[t] = -flow_value;
       _valid_supply = true;
     }
 
+    /// Destructor.
+    ~CycleCanceling() {
+      if (_local_flow) delete _flow;
+      if (_local_potential) delete _potential;
+      delete _res_graph;
+    }
+
+    /// \brief Sets the flow map.
+    ///
+    /// Sets the flow map.
+    ///
+    /// \return \c (*this)
+    CycleCanceling& flowMap(FlowMap &map) {
+      if (_local_flow) {
+        delete _flow;
+        _local_flow = false;
+      }
+      _flow = ↦
+      return *this;
+    }
+
+    /// \brief Sets the potential map.
+    ///
+    /// Sets the potential map.
+    ///
+    /// \return \c (*this)
+    CycleCanceling& potentialMap(PotentialMap &map) {
+      if (_local_potential) {
+        delete _potential;
+        _local_potential = false;
+      }
+      _potential = ↦
+      return *this;
+    }
+
+    /// \name Execution control
+    /// The only way to execute the algorithm is to call the run()
+    /// function.
+
+    /// @{
+
     /// \brief Runs the algorithm.
     ///
     /// Runs the algorithm.
@@ -281,6 +325,15 @@
       return init() && start(min_mean_cc);
     }
 
+    /// @}
+
+    /// \name Query Functions
+    /// The result of the algorithm can be obtained using these
+    /// functions.
+    /// \n run() must be called before using them.
+
+    /// @{
+
     /// \brief Returns a const reference to the edge map storing the
     /// found flow.
     ///
@@ -288,7 +341,36 @@
     ///
     /// \pre \ref run() must be called before using this function.
     const FlowMap& flowMap() const {
-      return _flow;
+      return *_flow;
+    }
+
+    /// \brief Returns a const reference to the node map storing the
+    /// found potentials (the dual solution).
+    ///
+    /// Returns a const reference to the node map storing the found
+    /// potentials (the dual solution).
+    ///
+    /// \pre \ref run() must be called before using this function.
+    const PotentialMap& potentialMap() const {
+      return *_potential;
+    }
+
+    /// \brief Returns the flow on the edge.
+    ///
+    /// Returns the flow on the edge.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Capacity flow(const Edge& edge) const {
+      return (*_flow)[edge];
+    }
+
+    /// \brief Returns the potential of the node.
+    ///
+    /// Returns the potential of the node.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Cost potential(const Node& node) const {
+      return (*_potential)[node];
     }
 
     /// \brief Returns the total cost of the found flow.
@@ -300,29 +382,50 @@
     Cost totalCost() const {
       Cost c = 0;
       for (EdgeIt e(_graph); e != INVALID; ++e)
-        c += _flow[e] * _cost[e];
+        c += (*_flow)[e] * _cost[e];
       return c;
     }
 
+    /// @}
+
   private:
 
     /// Initializes the algorithm.
     bool init() {
       if (!_valid_supply) return false;
 
+      // Initializing flow and potential maps
+      if (!_flow) {
+        _flow = new FlowMap(_graph);
+        _local_flow = true;
+      }
+      if (!_potential) {
+        _potential = new PotentialMap(_graph);
+        _local_potential = true;
+      }
+
+      _res_graph = new ResGraph(_graph, _capacity, *_flow);
+
       // Finding a feasible flow using Circulation
       Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
                    SupplyMap >
-        circulation( _graph, constMap<Edge>((Capacity)0), _capacity,
+        circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
                      _supply );
-      return circulation.flowMap(_flow).run();
+      return circulation.flowMap(*_flow).run();
     }
 
     bool start(bool min_mean_cc) {
       if (min_mean_cc)
-        return startMinMean();
+        startMinMean();
       else
-        return start();
+        start();
+
+      // Handling non-zero lower bounds
+      if (_lower) {
+        for (EdgeIt e(_graph); e != INVALID; ++e)
+          (*_flow)[e] += (*_lower)[e];
+      }
+      return true;
     }
 
     /// \brief Executes the algorithm using \ref BellmanFord.
@@ -330,16 +433,16 @@
     /// 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, ResidualCostMap>::PredMap pred(_res_graph);
-      typename ResGraph::template NodeMap<int> visited(_res_graph);
+    void start() {
+      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 length_bound = BF_FIRST_LIMIT;
       bool optimal = false;
       while (!optimal) {
-        BellmanFord<ResGraph, ResidualCostMap> bf(_res_graph, _res_cost);
+        BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost);
         bf.predMap(pred);
         bf.init(0);
         int iter_num = 0;
@@ -356,22 +459,26 @@
             }
           }
           if (real_iter_num < curr_iter_num) {
+            // Optimal flow is found
             optimal = true;
+            // Setting node potentials
+            for (NodeIt n(_graph); n != INVALID; ++n)
+              (*_potential)[n] = bf.dist(n);
             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
@@ -379,16 +486,16 @@
                 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);
                 }
 
                 // Augmenting along the cycle
                 for (int i = 0; i < int(cycle.size()); ++i)
-                  _res_graph.augment(cycle[i], d);
+                  _res_graph->augment(cycle[i], d);
               }
             }
           }
@@ -397,22 +504,15 @@
             length_bound = int(length_bound * BF_ALPHA);
         }
       }
-
-      // Handling non-zero lower bounds
-      if (_lower) {
-        for (EdgeIt e(_graph); e != INVALID; ++e)
-          _flow[e] += (*_lower)[e];
-      }
-      return true;
     }
 
     /// \brief Executes the algorithm using \ref MinMeanCycle.
     ///
     /// Executes the algorithm using \ref MinMeanCycle for negative
     /// cycle detection.
-    bool startMinMean() {
+    void startMinMean() {
       typedef Path<ResGraph> ResPath;
-      MinMeanCycle<ResGraph, ResidualCostMap> mmc(_res_graph, _res_cost);
+      MinMeanCycle<ResGraph, ResidualCostMap> mmc(*_res_graph, _res_cost);
       ResPath cycle;
 
       mmc.cyclePath(cycle).init();
@@ -425,13 +525,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
@@ -440,12 +540,11 @@
         }
       }
 
-      // Handling non-zero lower bounds
-      if (_lower) {
-        for (EdgeIt e(_graph); e != INVALID; ++e)
-          _flow[e] += (*_lower)[e];
-      }
-      return true;
+      // Computing node potentials
+      BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost);
+      bf.init(0); bf.start();
+      for (NodeIt n(_graph); n != INVALID; ++n)
+        (*_potential)[n] = bf.dist(n);
     }
 
   }; //class CycleCanceling

Modified: lemon/trunk/lemon/min_cost_flow.h
==============================================================================
--- lemon/trunk/lemon/min_cost_flow.h	(original)
+++ lemon/trunk/lemon/min_cost_flow.h	Thu Feb 28 03:54:27 2008
@@ -43,9 +43,7 @@
   /// \ref NetworkSimplex.
   ///
   /// There are four implementations for the minimum cost flow problem,
-  /// which can be used exactly the same way except for the fact that
-  /// \ref CycleCanceling does not provide dual solution (node
-  /// potentials) since it is a pure primal method.
+  /// which can be used exactly the same way.
   /// - \ref CapacityScaling The capacity scaling algorithm.
   /// - \ref CostScaling The cost scaling algorithm.
   /// - \ref CycleCanceling A cycle-canceling algorithm.
@@ -60,20 +58,16 @@
   /// \warning
   /// - 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.
+  /// - The value types of the maps should be convertible to each other.
+  /// - \c CostMap::Value must be signed type.
   ///
   /// \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 MinCostFlow :
     public NetworkSimplex< Graph, LowerMap, CapacityMap,
                            CostMap, SupplyMap >
@@ -85,7 +79,7 @@
 
   public:
 
-    /// General constructor of the class (with lower bounds).
+    /// General constructor (with lower bounds).
     MinCostFlow( const Graph &graph,
                  const LowerMap &lower,
                  const CapacityMap &capacity,
@@ -100,7 +94,7 @@
                  const SupplyMap &supply ) :
       MinCostFlowImpl(graph, capacity, cost, supply) {}
 
-    /// Simple constructor of the class (with lower bounds).
+    /// Simple constructor (with lower bounds).
     MinCostFlow( const Graph &graph,
                  const LowerMap &lower,
                  const CapacityMap &capacity,
@@ -110,7 +104,7 @@
       MinCostFlowImpl( graph, lower, capacity, cost,
                        s, t, flow_value ) {}
 
-    /// Simple constructor of the class (without lower bounds).
+    /// Simple constructor (without lower bounds).
     MinCostFlow( const Graph &graph,
                  const CapacityMap &capacity,
                  const CostMap &cost,

Modified: lemon/trunk/lemon/network_simplex.h
==============================================================================
--- lemon/trunk/lemon/network_simplex.h	(original)
+++ lemon/trunk/lemon/network_simplex.h	Thu Feb 28 03:54:27 2008
@@ -52,11 +52,8 @@
   /// \warning
   /// - 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.
+  /// - The value types of the maps should be convertible to each other.
+  /// - \c CostMap::Value must be signed type.
   ///
   /// \note \ref NetworkSimplex provides six different pivot rule
   /// implementations that significantly affect the efficiency of the
@@ -469,8 +466,10 @@
     ReducedCostMap _red_cost;
 
     // Members for handling the original graph
-    FlowMap _flow_result;
-    PotentialMap _potential_result;
+    FlowMap *_flow_result;
+    PotentialMap *_potential_result;
+    bool _local_flow;
+    bool _local_potential;
     NodeRefMap _node_ref;
     EdgeRefMap _edge_ref;
 
@@ -487,9 +486,9 @@
 
   public :
 
-    /// \brief General constructor of the class (with lower bounds).
+    /// \brief General constructor (with lower bounds).
     ///
-    /// General constructor of the class (with lower bounds).
+    /// General constructor (with lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param lower The lower bounds of the edges.
@@ -506,7 +505,8 @@
       _potential(_graph), _depth(_graph), _parent(_graph),
       _pred_edge(_graph), _thread(_graph), _forward(_graph),
       _state(_graph), _red_cost(_graph, _cost, _potential),
-      _flow_result(graph), _potential_result(graph),
+      _flow_result(0), _potential_result(0),
+      _local_flow(false), _local_potential(false),
       _node_ref(graph), _edge_ref(graph)
     {
       // Checking the sum of supply values
@@ -538,9 +538,9 @@
       }
     }
 
-    /// \brief General constructor of the class (without lower bounds).
+    /// \brief General constructor (without lower bounds).
     ///
-    /// General constructor of the class (without lower bounds).
+    /// General constructor (without lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param capacity The capacities (upper bounds) of the edges.
@@ -555,7 +555,8 @@
       _potential(_graph), _depth(_graph), _parent(_graph),
       _pred_edge(_graph), _thread(_graph), _forward(_graph),
       _state(_graph), _red_cost(_graph, _cost, _potential),
-      _flow_result(graph), _potential_result(graph),
+      _flow_result(0), _potential_result(0),
+      _local_flow(false), _local_potential(false),
       _node_ref(graph), _edge_ref(graph)
     {
       // Checking the sum of supply values
@@ -574,9 +575,9 @@
         .run();
     }
 
-    /// \brief Simple constructor of the class (with lower bounds).
+    /// \brief Simple constructor (with lower bounds).
     ///
-    /// Simple constructor of the class (with lower bounds).
+    /// Simple constructor (with lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param lower The lower bounds of the edges.
@@ -598,7 +599,8 @@
       _potential(_graph), _depth(_graph), _parent(_graph),
       _pred_edge(_graph), _thread(_graph), _forward(_graph),
       _state(_graph), _red_cost(_graph, _cost, _potential),
-      _flow_result(graph), _potential_result(graph),
+      _flow_result(0), _potential_result(0),
+      _local_flow(false), _local_potential(false),
       _node_ref(graph), _edge_ref(graph)
     {
       // Copying _graph_ref to graph
@@ -625,9 +627,9 @@
       _valid_supply = true;
     }
 
-    /// \brief Simple constructor of the class (without lower bounds).
+    /// \brief Simple constructor (without lower bounds).
     ///
-    /// Simple constructor of the class (without lower bounds).
+    /// Simple constructor (without lower bounds).
     ///
     /// \param graph The directed graph the algorithm runs on.
     /// \param capacity The capacities (upper bounds) of the edges.
@@ -647,7 +649,8 @@
       _potential(_graph), _depth(_graph), _parent(_graph),
       _pred_edge(_graph), _thread(_graph), _forward(_graph),
       _state(_graph), _red_cost(_graph, _cost, _potential),
-      _flow_result(graph), _potential_result(graph),
+      _flow_result(0), _potential_result(0),
+      _local_flow(false), _local_potential(false),
       _node_ref(graph), _edge_ref(graph)
     {
       // Copying _graph_ref to graph
@@ -662,6 +665,46 @@
       _valid_supply = true;
     }
 
+    /// Destructor.
+    ~NetworkSimplex() {
+      if (_local_flow) delete _flow_result;
+      if (_local_potential) delete _potential_result;
+    }
+
+    /// \brief Sets the flow map.
+    ///
+    /// Sets the flow map.
+    ///
+    /// \return \c (*this)
+    NetworkSimplex& flowMap(FlowMap &map) {
+      if (_local_flow) {
+        delete _flow_result;
+        _local_flow = false;
+      }
+      _flow_result = ↦
+      return *this;
+    }
+
+    /// \brief Sets the potential map.
+    ///
+    /// Sets the potential map.
+    ///
+    /// \return \c (*this)
+    NetworkSimplex& potentialMap(PotentialMap &map) {
+      if (_local_potential) {
+        delete _potential_result;
+        _local_potential = false;
+      }
+      _potential_result = ↦
+      return *this;
+    }
+
+    /// \name Execution control
+    /// The only way to execute the algorithm is to call the run()
+    /// function.
+
+    /// @{
+
     /// \brief Runs the algorithm.
     ///
     /// Runs the algorithm.
@@ -703,6 +746,15 @@
       return init() && start(pivot_rule);
     }
 
+    /// @}
+
+    /// \name Query Functions
+    /// The result of the algorithm can be obtained using these
+    /// functions.
+    /// \n run() must be called before using them.
+
+    /// @{
+
     /// \brief Returns a const reference to the edge map storing the
     /// found flow.
     ///
@@ -710,7 +762,7 @@
     ///
     /// \pre \ref run() must be called before using this function.
     const FlowMap& flowMap() const {
-      return _flow_result;
+      return *_flow_result;
     }
 
     /// \brief Returns a const reference to the node map storing the
@@ -721,7 +773,25 @@
     ///
     /// \pre \ref run() must be called before using this function.
     const PotentialMap& potentialMap() const {
-      return _potential_result;
+      return *_potential_result;
+    }
+
+    /// \brief Returns the flow on the edge.
+    ///
+    /// Returns the flow on the edge.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Capacity flow(const typename Graph::Edge& edge) const {
+      return (*_flow_result)[edge];
+    }
+
+    /// \brief Returns the potential of the node.
+    ///
+    /// Returns the potential of the node.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Cost potential(const typename Graph::Node& node) const {
+      return (*_potential_result)[node];
     }
 
     /// \brief Returns the total cost of the found flow.
@@ -733,10 +803,12 @@
     Cost totalCost() const {
       Cost c = 0;
       for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e)
-        c += _flow_result[e] * _cost[_edge_ref[e]];
+        c += (*_flow_result)[e] * _cost[_edge_ref[e]];
       return c;
     }
 
+    /// @}
+
   private:
 
     /// \brief Extends the underlaying graph and initializes all the
@@ -744,6 +816,16 @@
     bool init() {
       if (!_valid_supply) return false;
 
+      // Initializing result maps
+      if (!_flow_result) {
+        _flow_result = new FlowMap(_graph_ref);
+        _local_flow = true;
+      }
+      if (!_potential_result) {
+        _potential_result = new PotentialMap(_graph_ref);
+        _local_potential = true;
+      }
+
       // Initializing state and flow maps
       for (EdgeIt e(_graph); e != INVALID; ++e) {
         _flow[e] = 0;
@@ -1015,14 +1097,14 @@
       // Copying flow values to _flow_result
       if (_lower) {
         for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e)
-          _flow_result[e] = (*_lower)[e] + _flow[_edge_ref[e]];
+          (*_flow_result)[e] = (*_lower)[e] + _flow[_edge_ref[e]];
       } else {
         for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e)
-          _flow_result[e] = _flow[_edge_ref[e]];
+          (*_flow_result)[e] = _flow[_edge_ref[e]];
       }
       // Copying potential values to _potential_result
       for (typename Graph::NodeIt n(_graph_ref); n != INVALID; ++n)
-        _potential_result[n] = _potential[_node_ref[n]];
+        (*_potential_result)[n] = _potential[_node_ref[n]];
 
       return true;
     }



More information about the Lemon-commits mailing list