[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