[Lemon-commits] Peter Kovacs: Port CostScaling from SVN -r3524 (...

Lemon HG hg at lemon.cs.elte.hu
Mon Dec 14 06:17:45 CET 2009


details:   http://lemon.cs.elte.hu/hg/lemon/rev/9c428bb2b105
changeset: 874:9c428bb2b105
user:      Peter Kovacs <kpeter [at] inf.elte.hu>
date:      Thu Nov 12 23:29:42 2009 +0100
description:
	Port CostScaling from SVN -r3524 (#180)

diffstat:

 lemon/Makefile.am    |    3 +-
 lemon/cost_scaling.h |  850 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 852 insertions(+), 1 deletions(-)

diffs (truncated from 869 to 300 lines):

diff --git a/lemon/Makefile.am b/lemon/Makefile.am
--- a/lemon/Makefile.am
+++ b/lemon/Makefile.am
@@ -69,8 +69,9 @@
 	lemon/color.h \
 	lemon/concept_check.h \
 	lemon/connectivity.h \
+	lemon/core.h \
+	lemon/cost_scaling.h \
 	lemon/counter.h \
-	lemon/core.h \
 	lemon/cplex.h \
 	lemon/dfs.h \
 	lemon/dijkstra.h \
diff --git a/lemon/cost_scaling.h b/lemon/cost_scaling.h
new file mode 100644
--- /dev/null
+++ b/lemon/cost_scaling.h
@@ -0,0 +1,850 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_COST_SCALING_H
+#define LEMON_COST_SCALING_H
+
+/// \ingroup min_cost_flow_algs
+/// \file
+/// \brief Cost scaling algorithm for finding a minimum cost flow.
+
+#include <vector>
+#include <deque>
+#include <limits>
+
+#include <lemon/core.h>
+#include <lemon/maps.h>
+#include <lemon/math.h>
+#include <lemon/adaptors.h>
+#include <lemon/circulation.h>
+#include <lemon/bellman_ford.h>
+
+namespace lemon {
+
+  /// \addtogroup min_cost_flow_algs
+  /// @{
+
+  /// \brief Implementation of the cost scaling algorithm for finding a
+  /// minimum cost flow.
+  ///
+  /// \ref CostScaling implements the cost scaling algorithm performing
+  /// augment/push and relabel operations for finding a minimum cost
+  /// flow.
+  ///
+  /// \tparam Digraph The digraph 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
+  /// - Arc capacities and costs should be \e non-negative \e integers.
+  /// - Supply values should be \e signed \e integers.
+  /// - The value types of the maps should be convertible to each other.
+  /// - \c CostMap::Value must be signed type.
+  ///
+  /// \note Arc costs are multiplied with the number of nodes during
+  /// the algorithm so overflow problems may arise more easily than with
+  /// other minimum cost flow algorithms.
+  /// If it is available, <tt>long long int</tt> type is used instead of
+  /// <tt>long int</tt> in the inside computations.
+  ///
+  /// \author Peter Kovacs
+  template < typename Digraph,
+             typename LowerMap = typename Digraph::template ArcMap<int>,
+             typename CapacityMap = typename Digraph::template ArcMap<int>,
+             typename CostMap = typename Digraph::template ArcMap<int>,
+             typename SupplyMap = typename Digraph::template NodeMap<int> >
+  class CostScaling
+  {
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    typedef typename CapacityMap::Value Capacity;
+    typedef typename CostMap::Value Cost;
+    typedef typename SupplyMap::Value Supply;
+    typedef typename Digraph::template ArcMap<Capacity> CapacityArcMap;
+    typedef typename Digraph::template NodeMap<Supply> SupplyNodeMap;
+
+    typedef ResidualDigraph< const Digraph,
+                             CapacityArcMap, CapacityArcMap > ResDigraph;
+    typedef typename ResDigraph::Arc ResArc;
+
+#if defined __GNUC__ && !defined __STRICT_ANSI__
+    typedef long long int LCost;
+#else
+    typedef long int LCost;
+#endif
+    typedef typename Digraph::template ArcMap<LCost> LargeCostMap;
+
+  public:
+
+    /// The type of the flow map.
+    typedef typename Digraph::template ArcMap<Capacity> FlowMap;
+    /// The type of the potential map.
+    typedef typename Digraph::template NodeMap<LCost> PotentialMap;
+
+  private:
+
+    /// \brief Map adaptor class for handling residual arc costs.
+    ///
+    /// Map adaptor class for handling residual arc costs.
+    template <typename Map>
+    class ResidualCostMap : public MapBase<ResArc, typename Map::Value>
+    {
+    private:
+
+      const Map &_cost_map;
+
+    public:
+
+      ///\e
+      ResidualCostMap(const Map &cost_map) :
+        _cost_map(cost_map) {}
+
+      ///\e
+      inline typename Map::Value operator[](const ResArc &e) const {
+        return ResDigraph::forward(e) ? _cost_map[e] : -_cost_map[e];
+      }
+
+    }; //class ResidualCostMap
+
+    /// \brief Map adaptor class for handling reduced arc costs.
+    ///
+    /// Map adaptor class for handling reduced arc costs.
+    class ReducedCostMap : public MapBase<Arc, LCost>
+    {
+    private:
+
+      const Digraph &_gr;
+      const LargeCostMap &_cost_map;
+      const PotentialMap &_pot_map;
+
+    public:
+
+      ///\e
+      ReducedCostMap( const Digraph &gr,
+                      const LargeCostMap &cost_map,
+                      const PotentialMap &pot_map ) :
+        _gr(gr), _cost_map(cost_map), _pot_map(pot_map) {}
+
+      ///\e
+      inline LCost operator[](const Arc &e) const {
+        return _cost_map[e] + _pot_map[_gr.source(e)]
+                            - _pot_map[_gr.target(e)];
+      }
+
+    }; //class ReducedCostMap
+
+  private:
+
+    // The digraph the algorithm runs on
+    const Digraph &_graph;
+    // The original lower bound map
+    const LowerMap *_lower;
+    // The modified capacity map
+    CapacityArcMap _capacity;
+    // The original cost map
+    const CostMap &_orig_cost;
+    // The scaled cost map
+    LargeCostMap _cost;
+    // The modified supply map
+    SupplyNodeMap _supply;
+    bool _valid_supply;
+
+    // Arc map of the current flow
+    FlowMap *_flow;
+    bool _local_flow;
+    // Node map of the current potentials
+    PotentialMap *_potential;
+    bool _local_potential;
+
+    // The residual cost map
+    ResidualCostMap<LargeCostMap> _res_cost;
+    // The residual digraph
+    ResDigraph *_res_graph;
+    // The reduced cost map
+    ReducedCostMap *_red_cost;
+    // The excess map
+    SupplyNodeMap _excess;
+    // The epsilon parameter used for cost scaling
+    LCost _epsilon;
+    // The scaling factor
+    int _alpha;
+
+  public:
+
+    /// \brief General constructor (with lower bounds).
+    ///
+    /// General constructor (with lower bounds).
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param lower The lower bounds of the arcs.
+    /// \param capacity The capacities (upper bounds) of the arcs.
+    /// \param cost The cost (length) values of the arcs.
+    /// \param supply The supply values of the nodes (signed).
+    CostScaling( const Digraph &digraph,
+                 const LowerMap &lower,
+                 const CapacityMap &capacity,
+                 const CostMap &cost,
+                 const SupplyMap &supply ) :
+      _graph(digraph), _lower(&lower), _capacity(digraph), _orig_cost(cost),
+      _cost(digraph), _supply(digraph), _flow(NULL), _local_flow(false),
+      _potential(NULL), _local_potential(false), _res_cost(_cost),
+      _res_graph(NULL), _red_cost(NULL), _excess(digraph, 0)
+    {
+      // Check the sum of supply values
+      Supply sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
+      _valid_supply = sum == 0;
+      
+      for (ArcIt e(_graph); e != INVALID; ++e) _capacity[e] = capacity[e];
+      for (NodeIt n(_graph); n != INVALID; ++n) _supply[n] = supply[n];
+
+      // Remove non-zero lower bounds
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        if (lower[e] != 0) {
+          _capacity[e] -= lower[e];
+          _supply[_graph.source(e)] -= lower[e];
+          _supply[_graph.target(e)] += lower[e];
+        }
+      }
+    }
+/*
+    /// \brief General constructor (without lower bounds).
+    ///
+    /// General constructor (without lower bounds).
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param capacity The capacities (upper bounds) of the arcs.
+    /// \param cost The cost (length) values of the arcs.
+    /// \param supply The supply values of the nodes (signed).
+    CostScaling( const Digraph &digraph,
+                 const CapacityMap &capacity,
+                 const CostMap &cost,
+                 const SupplyMap &supply ) :
+      _graph(digraph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
+      _cost(digraph), _supply(supply), _flow(NULL), _local_flow(false),
+      _potential(NULL), _local_potential(false), _res_cost(_cost),
+      _res_graph(NULL), _red_cost(NULL), _excess(digraph, 0)
+    {
+      // Check the sum of supply values
+      Supply sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
+      _valid_supply = sum == 0;
+    }
+
+    /// \brief Simple constructor (with lower bounds).
+    ///
+    /// Simple constructor (with lower bounds).
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param lower The lower bounds of the arcs.
+    /// \param capacity The capacities (upper bounds) of the arcs.
+    /// \param cost The cost (length) values of the arcs.
+    /// \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).
+    CostScaling( const Digraph &digraph,
+                 const LowerMap &lower,
+                 const CapacityMap &capacity,
+                 const CostMap &cost,
+                 Node s, Node t,
+                 Supply flow_value ) :
+      _graph(digraph), _lower(&lower), _capacity(capacity), _orig_cost(cost),
+      _cost(digraph), _supply(digraph, 0), _flow(NULL), _local_flow(false),
+      _potential(NULL), _local_potential(false), _res_cost(_cost),
+      _res_graph(NULL), _red_cost(NULL), _excess(digraph, 0)
+    {
+      // Remove non-zero lower bounds
+      _supply[s] =  flow_value;
+      _supply[t] = -flow_value;
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        if (lower[e] != 0) {
+          _capacity[e] -= lower[e];
+          _supply[_graph.source(e)] -= lower[e];
+          _supply[_graph.target(e)] += lower[e];



More information about the Lemon-commits mailing list