[Lemon-commits] Balazs Dezso: Port MinCostArborescence algorithm...

Lemon HG hg at lemon.cs.elte.hu
Mon Feb 23 13:52:51 CET 2009


details:   http://lemon.cs.elte.hu/hg/lemon/rev/7f8560cb9d65
changeset: 544:7f8560cb9d65
user:      Balazs Dezso <deba [at] inf.elte.hu>
date:      Tue Dec 02 23:33:47 2008 +0100
description:
	Port MinCostArborescence algorithm from SVN #3509

diffstat:

5 files changed, 946 insertions(+)
lemon/Makefile.am                  |    1 
lemon/min_cost_arborescence.h      |  796 ++++++++++++++++++++++++++++++++++++
test/CMakeLists.txt                |    1 
test/Makefile.am                   |    2 
test/min_cost_arborescence_test.cc |  146 ++++++

diffs (truncated from 993 to 300 lines):

diff --git a/lemon/Makefile.am b/lemon/Makefile.am
--- a/lemon/Makefile.am
+++ b/lemon/Makefile.am
@@ -44,6 +44,7 @@
 	lemon/maps.h \
 	lemon/math.h \
 	lemon/max_matching.h \
+	lemon/min_cost_arborescence.h \
 	lemon/nauty_reader.h \
 	lemon/path.h \
 	lemon/preflow.h \
diff --git a/lemon/min_cost_arborescence.h b/lemon/min_cost_arborescence.h
new file mode 100644
--- /dev/null
+++ b/lemon/min_cost_arborescence.h
@@ -0,0 +1,796 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * 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_MIN_COST_ARBORESCENCE_H
+#define LEMON_MIN_COST_ARBORESCENCE_H
+
+///\ingroup spantree
+///\file
+///\brief Minimum Cost Arborescence algorithm.
+
+#include <vector>
+
+#include <lemon/list_graph.h>
+#include <lemon/bin_heap.h>
+#include <lemon/assert.h>
+
+namespace lemon {
+
+
+  /// \brief Default traits class for MinCostArborescence class.
+  ///
+  /// Default traits class for MinCostArborescence class.
+  /// \param _Digraph Digraph type.
+  /// \param _CostMap Type of cost map.
+  template <class _Digraph, class _CostMap>
+  struct MinCostArborescenceDefaultTraits{
+
+    /// \brief The digraph type the algorithm runs on.
+    typedef _Digraph Digraph;
+
+    /// \brief The type of the map that stores the arc costs.
+    ///
+    /// The type of the map that stores the arc costs.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef _CostMap CostMap;
+
+    /// \brief The value type of the costs.
+    ///
+    /// The value type of the costs.
+    typedef typename CostMap::Value Value;
+
+    /// \brief The type of the map that stores which arcs are in the
+    /// arborescence.
+    ///
+    /// The type of the map that stores which arcs are in the
+    /// arborescence.  It must meet the \ref concepts::WriteMap
+    /// "WriteMap" concept.  Initially it will be set to false on each
+    /// arc. After it will set all arborescence arcs once.
+    typedef typename Digraph::template ArcMap<bool> ArborescenceMap;
+
+    /// \brief Instantiates a ArborescenceMap.
+    ///
+    /// This function instantiates a \ref ArborescenceMap.
+    /// \param digraph is the graph, to which we would like to
+    /// calculate the ArborescenceMap.
+    static ArborescenceMap *createArborescenceMap(const Digraph &digraph){
+      return new ArborescenceMap(digraph);
+    }
+
+    /// \brief The type of the PredMap
+    ///
+    /// The type of the PredMap. It is a node map with an arc value type.
+    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
+
+    /// \brief Instantiates a PredMap.
+    ///
+    /// This function instantiates a \ref PredMap.
+    /// \param _digraph is the digraph, to which we would like to define the
+    /// PredMap.
+    static PredMap *createPredMap(const Digraph &digraph){
+      return new PredMap(digraph);
+    }
+
+  };
+
+  /// \ingroup spantree
+  ///
+  /// \brief %MinCostArborescence algorithm class.
+  ///
+  /// This class provides an efficient implementation of
+  /// %MinCostArborescence algorithm. The arborescence is a tree
+  /// which is directed from a given source node of the digraph. One or
+  /// more sources should be given for the algorithm and it will calculate
+  /// the minimum cost subgraph which are union of arborescences with the
+  /// given sources and spans all the nodes which are reachable from the
+  /// sources. The time complexity of the algorithm is \f$ O(n^2+e) \f$.
+  ///
+  /// The algorithm provides also an optimal dual solution, therefore
+  /// the optimality of the solution can be checked.
+  ///
+  /// \param _Digraph The digraph type the algorithm runs on. The default value
+  /// is \ref ListDigraph.
+  /// \param _CostMap This read-only ArcMap determines the costs of the
+  /// arcs. It is read once for each arc, so the map may involve in
+  /// relatively time consuming process to compute the arc cost if
+  /// it is necessary. The default map type is \ref
+  /// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
+  /// \param _Traits Traits class to set various data types used
+  /// by the algorithm. The default traits class is
+  /// \ref MinCostArborescenceDefaultTraits
+  /// "MinCostArborescenceDefaultTraits<_Digraph, _CostMap>".  See \ref
+  /// MinCostArborescenceDefaultTraits for the documentation of a
+  /// MinCostArborescence traits class.
+  ///
+  /// \author Balazs Dezso
+#ifndef DOXYGEN
+  template <typename _Digraph = ListDigraph,
+            typename _CostMap = typename _Digraph::template ArcMap<int>,
+            typename _Traits =
+            MinCostArborescenceDefaultTraits<_Digraph, _CostMap> >
+#else
+  template <typename _Digraph, typename _CostMap, typedef _Traits>
+#endif
+  class MinCostArborescence {
+  public:
+
+    /// The traits.
+    typedef _Traits Traits;
+    /// The type of the underlying digraph.
+    typedef typename Traits::Digraph Digraph;
+    /// The type of the map that stores the arc costs.
+    typedef typename Traits::CostMap CostMap;
+    ///The type of the costs of the arcs.
+    typedef typename Traits::Value Value;
+    ///The type of the predecessor map.
+    typedef typename Traits::PredMap PredMap;
+    ///The type of the map that stores which arcs are in the arborescence.
+    typedef typename Traits::ArborescenceMap ArborescenceMap;
+
+    typedef MinCostArborescence Create;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    struct CostArc {
+
+      Arc arc;
+      Value value;
+
+      CostArc() {}
+      CostArc(Arc _arc, Value _value) : arc(_arc), value(_value) {}
+
+    };
+
+    const Digraph *_digraph;
+    const CostMap *_cost;
+
+    PredMap *_pred;
+    bool local_pred;
+
+    ArborescenceMap *_arborescence;
+    bool local_arborescence;
+
+    typedef typename Digraph::template ArcMap<int> ArcOrder;
+    ArcOrder *_arc_order;
+
+    typedef typename Digraph::template NodeMap<int> NodeOrder;
+    NodeOrder *_node_order;
+
+    typedef typename Digraph::template NodeMap<CostArc> CostArcMap;
+    CostArcMap *_cost_arcs;
+
+    struct StackLevel {
+
+      std::vector<CostArc> arcs;
+      int node_level;
+
+    };
+
+    std::vector<StackLevel> level_stack;
+    std::vector<Node> queue;
+
+    typedef std::vector<typename Digraph::Node> DualNodeList;
+
+    DualNodeList _dual_node_list;
+
+    struct DualVariable {
+      int begin, end;
+      Value value;
+
+      DualVariable(int _begin, int _end, Value _value)
+        : begin(_begin), end(_end), value(_value) {}
+
+    };
+
+    typedef std::vector<DualVariable> DualVariables;
+
+    DualVariables _dual_variables;
+
+    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
+
+    HeapCrossRef *_heap_cross_ref;
+
+    typedef BinHeap<int, HeapCrossRef> Heap;
+
+    Heap *_heap;
+
+  protected:
+
+    MinCostArborescence() {}
+
+  private:
+
+    void createStructures() {
+      if (!_pred) {
+        local_pred = true;
+        _pred = Traits::createPredMap(*_digraph);
+      }
+      if (!_arborescence) {
+        local_arborescence = true;
+        _arborescence = Traits::createArborescenceMap(*_digraph);
+      }
+      if (!_arc_order) {
+        _arc_order = new ArcOrder(*_digraph);
+      }
+      if (!_node_order) {
+        _node_order = new NodeOrder(*_digraph);
+      }
+      if (!_cost_arcs) {
+        _cost_arcs = new CostArcMap(*_digraph);
+      }
+      if (!_heap_cross_ref) {
+        _heap_cross_ref = new HeapCrossRef(*_digraph, -1);
+      }
+      if (!_heap) {
+        _heap = new Heap(*_heap_cross_ref);
+      }
+    }
+
+    void destroyStructures() {
+      if (local_arborescence) {
+        delete _arborescence;
+      }
+      if (local_pred) {
+        delete _pred;
+      }
+      if (_arc_order) {
+        delete _arc_order;
+      }
+      if (_node_order) {
+        delete _node_order;
+      }
+      if (_cost_arcs) {
+        delete _cost_arcs;
+      }
+      if (_heap) {
+        delete _heap;
+      }
+      if (_heap_cross_ref) {
+        delete _heap_cross_ref;
+      }
+    }
+
+    Arc prepare(Node node) {
+      std::vector<Node> nodes;
+      (*_node_order)[node] = _dual_node_list.size();
+      StackLevel level;
+      level.node_level = _dual_node_list.size();
+      _dual_node_list.push_back(node);
+      for (InArcIt it(*_digraph, node); it != INVALID; ++it) {
+        Arc arc = it;
+        Node source = _digraph->source(arc);
+        Value value = (*_cost)[it];
+        if (source == node || (*_node_order)[source] == -3) continue;
+        if ((*_cost_arcs)[source].arc == INVALID) {
+          (*_cost_arcs)[source].arc = arc;
+          (*_cost_arcs)[source].value = value;
+          nodes.push_back(source);



More information about the Lemon-commits mailing list