[Lemon-commits] Peter Kovacs: Entirely rework CostScaling (#180)
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/22bb98ca0101
changeset: 875:22bb98ca0101
user: Peter Kovacs <kpeter [at] inf.elte.hu>
date: Thu Nov 12 23:30:45 2009 +0100
description:
Entirely rework CostScaling (#180)
- Use the new interface similarly to NetworkSimplex.
- Rework the implementation using an efficient internal structure
for handling the residual network. This improvement made the
code much faster.
- Handle GEQ supply type (LEQ is not supported).
- Handle infinite upper bounds.
- Handle negative costs (for arcs of finite upper bound).
- Traits class + named parameter for the LargeCost type used in
internal computations.
- Extend the documentation.
diffstat:
lemon/cost_scaling.h | 1436 +++++++++++++++++++++++++++++++---------------------
1 files changed, 860 insertions(+), 576 deletions(-)
diffs (truncated from 1679 to 300 lines):
diff --git a/lemon/cost_scaling.h b/lemon/cost_scaling.h
--- a/lemon/cost_scaling.h
+++ b/lemon/cost_scaling.h
@@ -30,548 +30,912 @@
#include <lemon/core.h>
#include <lemon/maps.h>
#include <lemon/math.h>
-#include <lemon/adaptors.h>
+#include <lemon/static_graph.h>
#include <lemon/circulation.h>
#include <lemon/bellman_ford.h>
namespace lemon {
+ /// \brief Default traits class of CostScaling algorithm.
+ ///
+ /// Default traits class of CostScaling algorithm.
+ /// \tparam GR Digraph type.
+ /// \tparam V The value type used for flow amounts, capacity bounds
+ /// and supply values. By default it is \c int.
+ /// \tparam C The value type used for costs and potentials.
+ /// By default it is the same as \c V.
+#ifdef DOXYGEN
+ template <typename GR, typename V = int, typename C = V>
+#else
+ template < typename GR, typename V = int, typename C = V,
+ bool integer = std::numeric_limits<C>::is_integer >
+#endif
+ struct CostScalingDefaultTraits
+ {
+ /// The type of the digraph
+ typedef GR Digraph;
+ /// The type of the flow amounts, capacity bounds and supply values
+ typedef V Value;
+ /// The type of the arc costs
+ typedef C Cost;
+
+ /// \brief The large cost type used for internal computations
+ ///
+ /// The large cost type used for internal computations.
+ /// It is \c long \c long if the \c Cost type is integer,
+ /// otherwise it is \c double.
+ /// \c Cost must be convertible to \c LargeCost.
+ typedef double LargeCost;
+ };
+
+ // Default traits class for integer cost types
+ template <typename GR, typename V, typename C>
+ struct CostScalingDefaultTraits<GR, V, C, true>
+ {
+ typedef GR Digraph;
+ typedef V Value;
+ typedef C Cost;
+#ifdef LEMON_HAVE_LONG_LONG
+ typedef long long LargeCost;
+#else
+ typedef long LargeCost;
+#endif
+ };
+
+
/// \addtogroup min_cost_flow_algs
/// @{
- /// \brief Implementation of the cost scaling algorithm for finding a
- /// minimum cost flow.
+ /// \brief Implementation of the Cost Scaling algorithm for
+ /// finding a \ref min_cost_flow "minimum cost flow".
///
- /// \ref CostScaling implements the cost scaling algorithm performing
- /// augment/push and relabel operations for finding a minimum cost
- /// flow.
+ /// \ref CostScaling implements a cost scaling algorithm that performs
+ /// push/augment and relabel operations for finding a minimum cost
+ /// flow. It is an efficient primal-dual solution method, which
+ /// can be viewed as the generalization of the \ref Preflow
+ /// "preflow push-relabel" algorithm for the maximum flow problem.
///
- /// \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.
+ /// Most of the parameters of the problem (except for the digraph)
+ /// can be given using separate functions, and the algorithm can be
+ /// executed using the \ref run() function. If some parameters are not
+ /// specified, then default values will be used.
///
- /// \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.
+ /// \tparam GR The digraph type the algorithm runs on.
+ /// \tparam V The value type used for flow amounts, capacity bounds
+ /// and supply values in the algorithm. By default it is \c int.
+ /// \tparam C The value type used for costs and potentials in the
+ /// algorithm. By default it is the same as \c V.
///
- /// \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> >
+ /// \warning Both value types must be signed and all input data must
+ /// be integer.
+ /// \warning This algorithm does not support negative costs for such
+ /// arcs that have infinite upper bound.
+#ifdef DOXYGEN
+ template <typename GR, typename V, typename C, typename TR>
+#else
+ template < typename GR, typename V = int, typename C = V,
+ typename TR = CostScalingDefaultTraits<GR, V, C> >
+#endif
class CostScaling
{
- TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+ public:
- 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;
+ /// The type of the digraph
+ typedef typename TR::Digraph Digraph;
+ /// The type of the flow amounts, capacity bounds and supply values
+ typedef typename TR::Value Value;
+ /// The type of the arc costs
+ typedef typename TR::Cost Cost;
- typedef ResidualDigraph< const Digraph,
- CapacityArcMap, CapacityArcMap > ResDigraph;
- typedef typename ResDigraph::Arc ResArc;
+ /// \brief The large cost type
+ ///
+ /// The large cost type used for internal computations.
+ /// Using the \ref CostScalingDefaultTraits "default traits class",
+ /// it is \c long \c long if the \c Cost type is integer,
+ /// otherwise it is \c double.
+ typedef typename TR::LargeCost LargeCost;
-#if defined __GNUC__ && !defined __STRICT_ANSI__
- typedef long long int LCost;
-#else
- typedef long int LCost;
-#endif
- typedef typename Digraph::template ArcMap<LCost> LargeCostMap;
+ /// The \ref CostScalingDefaultTraits "traits class" of the algorithm
+ typedef TR Traits;
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;
+ /// \brief Problem type constants for the \c run() function.
+ ///
+ /// Enum type containing the problem type constants that can be
+ /// returned by the \ref run() function of the algorithm.
+ enum ProblemType {
+ /// The problem has no feasible solution (flow).
+ INFEASIBLE,
+ /// The problem has optimal solution (i.e. it is feasible and
+ /// bounded), and the algorithm has found optimal flow and node
+ /// potentials (primal and dual solutions).
+ OPTIMAL,
+ /// The digraph contains an arc of negative cost and infinite
+ /// upper bound. It means that the objective function is unbounded
+ /// on that arc, however note that it could actually be bounded
+ /// over the feasible flows, but this algroithm cannot handle
+ /// these cases.
+ UNBOUNDED
+ };
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:
+ TEMPLATE_DIGRAPH_TYPEDEFS(GR);
- const Map &_cost_map;
+ typedef std::vector<int> IntVector;
+ typedef std::vector<char> BoolVector;
+ typedef std::vector<Value> ValueVector;
+ typedef std::vector<Cost> CostVector;
+ typedef std::vector<LargeCost> LargeCostVector;
+ private:
+
+ template <typename KT, typename VT>
+ class VectorMap {
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];
+ typedef KT Key;
+ typedef VT Value;
+
+ VectorMap(std::vector<Value>& v) : _v(v) {}
+
+ const Value& operator[](const Key& key) const {
+ return _v[StaticDigraph::id(key)];
}
- }; //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)];
+ Value& operator[](const Key& key) {
+ return _v[StaticDigraph::id(key)];
+ }
+
+ void set(const Key& key, const Value& val) {
+ _v[StaticDigraph::id(key)] = val;
}
- }; //class ReducedCostMap
+ private:
+ std::vector<Value>& _v;
+ };
+
+ typedef VectorMap<StaticDigraph::Node, LargeCost> LargeCostNodeMap;
+ typedef VectorMap<StaticDigraph::Arc, LargeCost> LargeCostArcMap;
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;
+ // Data related to the underlying digraph
+ const GR &_graph;
+ int _node_num;
+ int _arc_num;
+ int _res_node_num;
+ int _res_arc_num;
+ int _root;
- // Arc map of the current flow
- FlowMap *_flow;
- bool _local_flow;
- // Node map of the current potentials
- PotentialMap *_potential;
- bool _local_potential;
+ // Parameters of the problem
+ bool _have_lower;
+ Value _sum_supply;
- // The residual cost map
- ResidualCostMap<LargeCostMap> _res_cost;
- // The residual digraph
More information about the Lemon-commits
mailing list