deba@522: /* -*- mode: C++; indent-tabs-mode: nil; -*- deba@522: * deba@522: * This file is a part of LEMON, a generic C++ optimization library. deba@522: * deba@522: * Copyright (C) 2003-2008 deba@522: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@522: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@522: * deba@522: * Permission to use, modify and distribute this software is granted deba@522: * provided that this copyright notice appears in all copies. For deba@522: * precise terms see the accompanying LICENSE file. deba@522: * deba@522: * This software is provided "AS IS" with no warranty of any kind, deba@522: * express or implied, and with no claim as to its suitability for any deba@522: * purpose. deba@522: * deba@522: */ deba@522: deba@522: #ifndef LEMON_MIN_COST_ARBORESCENCE_H deba@522: #define LEMON_MIN_COST_ARBORESCENCE_H deba@522: deba@522: ///\ingroup spantree deba@522: ///\file deba@522: ///\brief Minimum Cost Arborescence algorithm. deba@522: deba@522: #include deba@522: deba@522: #include deba@522: #include deba@522: #include deba@522: deba@522: namespace lemon { deba@522: deba@522: deba@522: /// \brief Default traits class for MinCostArborescence class. deba@522: /// deba@522: /// Default traits class for MinCostArborescence class. kpeter@606: /// \param GR Digraph type. kpeter@672: /// \param CM Type of the cost map. kpeter@606: template deba@522: struct MinCostArborescenceDefaultTraits{ deba@522: deba@522: /// \brief The digraph type the algorithm runs on. kpeter@606: typedef GR Digraph; deba@522: deba@522: /// \brief The type of the map that stores the arc costs. deba@522: /// deba@522: /// The type of the map that stores the arc costs. kpeter@672: /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. kpeter@606: typedef CM CostMap; deba@522: deba@522: /// \brief The value type of the costs. deba@522: /// deba@522: /// The value type of the costs. deba@522: typedef typename CostMap::Value Value; deba@522: deba@522: /// \brief The type of the map that stores which arcs are in the deba@522: /// arborescence. deba@522: /// deba@522: /// The type of the map that stores which arcs are in the kpeter@672: /// arborescence. It must conform to the \ref concepts::WriteMap kpeter@672: /// "WriteMap" concept, and its value type must be \c bool kpeter@672: /// (or convertible). Initially it will be set to \c false on each kpeter@672: /// arc, then it will be set on each arborescence arc once. deba@522: typedef typename Digraph::template ArcMap ArborescenceMap; deba@522: kpeter@606: /// \brief Instantiates a \c ArborescenceMap. deba@522: /// kpeter@606: /// This function instantiates a \c ArborescenceMap. kpeter@672: /// \param digraph The digraph to which we would like to calculate kpeter@672: /// the \c ArborescenceMap. deba@522: static ArborescenceMap *createArborescenceMap(const Digraph &digraph){ deba@522: return new ArborescenceMap(digraph); deba@522: } deba@522: kpeter@606: /// \brief The type of the \c PredMap deba@522: /// kpeter@672: /// The type of the \c PredMap. It must confrom to the kpeter@672: /// \ref concepts::WriteMap "WriteMap" concept, and its value type kpeter@672: /// must be the \c Arc type of the digraph. deba@522: typedef typename Digraph::template NodeMap PredMap; deba@522: kpeter@606: /// \brief Instantiates a \c PredMap. deba@522: /// kpeter@606: /// This function instantiates a \c PredMap. kpeter@606: /// \param digraph The digraph to which we would like to define the kpeter@606: /// \c PredMap. deba@522: static PredMap *createPredMap(const Digraph &digraph){ deba@522: return new PredMap(digraph); deba@522: } deba@522: deba@522: }; deba@522: deba@522: /// \ingroup spantree deba@522: /// kpeter@631: /// \brief Minimum Cost Arborescence algorithm class. deba@522: /// kpeter@672: /// This class provides an efficient implementation of the kpeter@631: /// Minimum Cost Arborescence algorithm. The arborescence is a tree deba@522: /// which is directed from a given source node of the digraph. One or kpeter@672: /// more sources should be given to the algorithm and it will calculate kpeter@672: /// the minimum cost subgraph that is the union of arborescences with the deba@522: /// given sources and spans all the nodes which are reachable from the kpeter@606: /// sources. The time complexity of the algorithm is O(n2+e). deba@522: /// kpeter@672: /// The algorithm also provides an optimal dual solution, therefore deba@522: /// the optimality of the solution can be checked. deba@522: /// kpeter@672: /// \param GR The digraph type the algorithm runs on. kpeter@672: /// \param CM A read-only arc map storing the costs of the deba@522: /// arcs. It is read once for each arc, so the map may involve in kpeter@672: /// relatively time consuming process to compute the arc costs if deba@522: /// it is necessary. The default map type is \ref deba@522: /// concepts::Digraph::ArcMap "Digraph::ArcMap". kpeter@606: /// \param TR Traits class to set various data types used deba@522: /// by the algorithm. The default traits class is deba@522: /// \ref MinCostArborescenceDefaultTraits kpeter@672: /// "MinCostArborescenceDefaultTraits". deba@522: #ifndef DOXYGEN kpeter@672: template , kpeter@606: typename TR = kpeter@606: MinCostArborescenceDefaultTraits > deba@522: #else kpeter@606: template deba@522: #endif deba@522: class MinCostArborescence { deba@522: public: deba@522: kpeter@672: /// \brief The \ref MinCostArborescenceDefaultTraits "traits class" kpeter@672: /// of the algorithm. kpeter@606: typedef TR Traits; deba@522: /// The type of the underlying digraph. deba@522: typedef typename Traits::Digraph Digraph; deba@522: /// The type of the map that stores the arc costs. deba@522: typedef typename Traits::CostMap CostMap; deba@522: ///The type of the costs of the arcs. deba@522: typedef typename Traits::Value Value; deba@522: ///The type of the predecessor map. deba@522: typedef typename Traits::PredMap PredMap; deba@522: ///The type of the map that stores which arcs are in the arborescence. deba@522: typedef typename Traits::ArborescenceMap ArborescenceMap; deba@522: deba@522: typedef MinCostArborescence Create; deba@522: deba@522: private: deba@522: deba@522: TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); deba@522: deba@522: struct CostArc { deba@522: deba@522: Arc arc; deba@522: Value value; deba@522: deba@522: CostArc() {} deba@522: CostArc(Arc _arc, Value _value) : arc(_arc), value(_value) {} deba@522: deba@522: }; deba@522: deba@522: const Digraph *_digraph; deba@522: const CostMap *_cost; deba@522: deba@522: PredMap *_pred; deba@522: bool local_pred; deba@522: deba@522: ArborescenceMap *_arborescence; deba@522: bool local_arborescence; deba@522: deba@522: typedef typename Digraph::template ArcMap ArcOrder; deba@522: ArcOrder *_arc_order; deba@522: deba@522: typedef typename Digraph::template NodeMap NodeOrder; deba@522: NodeOrder *_node_order; deba@522: deba@522: typedef typename Digraph::template NodeMap CostArcMap; deba@522: CostArcMap *_cost_arcs; deba@522: deba@522: struct StackLevel { deba@522: deba@522: std::vector arcs; deba@522: int node_level; deba@522: deba@522: }; deba@522: deba@522: std::vector level_stack; deba@522: std::vector queue; deba@522: deba@522: typedef std::vector DualNodeList; deba@522: deba@522: DualNodeList _dual_node_list; deba@522: deba@522: struct DualVariable { deba@522: int begin, end; deba@522: Value value; deba@522: deba@522: DualVariable(int _begin, int _end, Value _value) deba@522: : begin(_begin), end(_end), value(_value) {} deba@522: deba@522: }; deba@522: deba@522: typedef std::vector DualVariables; deba@522: deba@522: DualVariables _dual_variables; deba@522: deba@522: typedef typename Digraph::template NodeMap HeapCrossRef; deba@522: deba@522: HeapCrossRef *_heap_cross_ref; deba@522: deba@522: typedef BinHeap Heap; deba@522: deba@522: Heap *_heap; deba@522: deba@522: protected: deba@522: deba@522: MinCostArborescence() {} deba@522: deba@522: private: deba@522: deba@522: void createStructures() { deba@522: if (!_pred) { deba@522: local_pred = true; deba@522: _pred = Traits::createPredMap(*_digraph); deba@522: } deba@522: if (!_arborescence) { deba@522: local_arborescence = true; deba@522: _arborescence = Traits::createArborescenceMap(*_digraph); deba@522: } deba@522: if (!_arc_order) { deba@522: _arc_order = new ArcOrder(*_digraph); deba@522: } deba@522: if (!_node_order) { deba@522: _node_order = new NodeOrder(*_digraph); deba@522: } deba@522: if (!_cost_arcs) { deba@522: _cost_arcs = new CostArcMap(*_digraph); deba@522: } deba@522: if (!_heap_cross_ref) { deba@522: _heap_cross_ref = new HeapCrossRef(*_digraph, -1); deba@522: } deba@522: if (!_heap) { deba@522: _heap = new Heap(*_heap_cross_ref); deba@522: } deba@522: } deba@522: deba@522: void destroyStructures() { deba@522: if (local_arborescence) { deba@522: delete _arborescence; deba@522: } deba@522: if (local_pred) { deba@522: delete _pred; deba@522: } deba@522: if (_arc_order) { deba@522: delete _arc_order; deba@522: } deba@522: if (_node_order) { deba@522: delete _node_order; deba@522: } deba@522: if (_cost_arcs) { deba@522: delete _cost_arcs; deba@522: } deba@522: if (_heap) { deba@522: delete _heap; deba@522: } deba@522: if (_heap_cross_ref) { deba@522: delete _heap_cross_ref; deba@522: } deba@522: } deba@522: deba@522: Arc prepare(Node node) { deba@522: std::vector nodes; deba@522: (*_node_order)[node] = _dual_node_list.size(); deba@522: StackLevel level; deba@522: level.node_level = _dual_node_list.size(); deba@522: _dual_node_list.push_back(node); deba@522: for (InArcIt it(*_digraph, node); it != INVALID; ++it) { deba@522: Arc arc = it; deba@522: Node source = _digraph->source(arc); deba@522: Value value = (*_cost)[it]; deba@522: if (source == node || (*_node_order)[source] == -3) continue; deba@522: if ((*_cost_arcs)[source].arc == INVALID) { deba@522: (*_cost_arcs)[source].arc = arc; deba@522: (*_cost_arcs)[source].value = value; deba@522: nodes.push_back(source); deba@522: } else { deba@522: if ((*_cost_arcs)[source].value > value) { deba@522: (*_cost_arcs)[source].arc = arc; deba@522: (*_cost_arcs)[source].value = value; deba@522: } deba@522: } deba@522: } deba@522: CostArc minimum = (*_cost_arcs)[nodes[0]]; deba@522: for (int i = 1; i < int(nodes.size()); ++i) { deba@522: if ((*_cost_arcs)[nodes[i]].value < minimum.value) { deba@522: minimum = (*_cost_arcs)[nodes[i]]; deba@522: } deba@522: } kpeter@628: (*_arc_order)[minimum.arc] = _dual_variables.size(); deba@522: DualVariable var(_dual_node_list.size() - 1, deba@522: _dual_node_list.size(), minimum.value); deba@522: _dual_variables.push_back(var); deba@522: for (int i = 0; i < int(nodes.size()); ++i) { deba@522: (*_cost_arcs)[nodes[i]].value -= minimum.value; deba@522: level.arcs.push_back((*_cost_arcs)[nodes[i]]); deba@522: (*_cost_arcs)[nodes[i]].arc = INVALID; deba@522: } deba@522: level_stack.push_back(level); deba@522: return minimum.arc; deba@522: } deba@522: deba@522: Arc contract(Node node) { deba@522: int node_bottom = bottom(node); deba@522: std::vector nodes; deba@522: while (!level_stack.empty() && deba@522: level_stack.back().node_level >= node_bottom) { deba@522: for (int i = 0; i < int(level_stack.back().arcs.size()); ++i) { deba@522: Arc arc = level_stack.back().arcs[i].arc; deba@522: Node source = _digraph->source(arc); deba@522: Value value = level_stack.back().arcs[i].value; deba@522: if ((*_node_order)[source] >= node_bottom) continue; deba@522: if ((*_cost_arcs)[source].arc == INVALID) { deba@522: (*_cost_arcs)[source].arc = arc; deba@522: (*_cost_arcs)[source].value = value; deba@522: nodes.push_back(source); deba@522: } else { deba@522: if ((*_cost_arcs)[source].value > value) { deba@522: (*_cost_arcs)[source].arc = arc; deba@522: (*_cost_arcs)[source].value = value; deba@522: } deba@522: } deba@522: } deba@522: level_stack.pop_back(); deba@522: } deba@522: CostArc minimum = (*_cost_arcs)[nodes[0]]; deba@522: for (int i = 1; i < int(nodes.size()); ++i) { deba@522: if ((*_cost_arcs)[nodes[i]].value < minimum.value) { deba@522: minimum = (*_cost_arcs)[nodes[i]]; deba@522: } deba@522: } kpeter@628: (*_arc_order)[minimum.arc] = _dual_variables.size(); deba@522: DualVariable var(node_bottom, _dual_node_list.size(), minimum.value); deba@522: _dual_variables.push_back(var); deba@522: StackLevel level; deba@522: level.node_level = node_bottom; deba@522: for (int i = 0; i < int(nodes.size()); ++i) { deba@522: (*_cost_arcs)[nodes[i]].value -= minimum.value; deba@522: level.arcs.push_back((*_cost_arcs)[nodes[i]]); deba@522: (*_cost_arcs)[nodes[i]].arc = INVALID; deba@522: } deba@522: level_stack.push_back(level); deba@522: return minimum.arc; deba@522: } deba@522: deba@522: int bottom(Node node) { deba@522: int k = level_stack.size() - 1; deba@522: while (level_stack[k].node_level > (*_node_order)[node]) { deba@522: --k; deba@522: } deba@522: return level_stack[k].node_level; deba@522: } deba@522: deba@522: void finalize(Arc arc) { deba@522: Node node = _digraph->target(arc); deba@522: _heap->push(node, (*_arc_order)[arc]); deba@522: _pred->set(node, arc); deba@522: while (!_heap->empty()) { deba@522: Node source = _heap->top(); deba@522: _heap->pop(); kpeter@628: (*_node_order)[source] = -1; deba@522: for (OutArcIt it(*_digraph, source); it != INVALID; ++it) { deba@522: if ((*_arc_order)[it] < 0) continue; deba@522: Node target = _digraph->target(it); deba@522: switch(_heap->state(target)) { deba@522: case Heap::PRE_HEAP: deba@522: _heap->push(target, (*_arc_order)[it]); deba@522: _pred->set(target, it); deba@522: break; deba@522: case Heap::IN_HEAP: deba@522: if ((*_arc_order)[it] < (*_heap)[target]) { deba@522: _heap->decrease(target, (*_arc_order)[it]); deba@522: _pred->set(target, it); deba@522: } deba@522: break; deba@522: case Heap::POST_HEAP: deba@522: break; deba@522: } deba@522: } deba@522: _arborescence->set((*_pred)[source], true); deba@522: } deba@522: } deba@522: deba@522: deba@522: public: deba@522: kpeter@631: /// \name Named Template Parameters deba@522: deba@522: /// @{ deba@522: deba@522: template kpeter@672: struct SetArborescenceMapTraits : public Traits { deba@522: typedef T ArborescenceMap; deba@522: static ArborescenceMap *createArborescenceMap(const Digraph &) deba@522: { deba@522: LEMON_ASSERT(false, "ArborescenceMap is not initialized"); deba@522: return 0; // ignore warnings deba@522: } deba@522: }; deba@522: deba@522: /// \brief \ref named-templ-param "Named parameter" for kpeter@672: /// setting \c ArborescenceMap type deba@522: /// deba@522: /// \ref named-templ-param "Named parameter" for setting kpeter@672: /// \c ArborescenceMap type. kpeter@672: /// It must conform to the \ref concepts::WriteMap "WriteMap" concept, kpeter@672: /// and its value type must be \c bool (or convertible). kpeter@672: /// Initially it will be set to \c false on each arc, kpeter@672: /// then it will be set on each arborescence arc once. deba@522: template kpeter@672: struct SetArborescenceMap deba@522: : public MinCostArborescence > { deba@522: }; deba@522: deba@522: template kpeter@672: struct SetPredMapTraits : public Traits { deba@522: typedef T PredMap; deba@522: static PredMap *createPredMap(const Digraph &) deba@522: { deba@522: LEMON_ASSERT(false, "PredMap is not initialized"); kpeter@672: return 0; // ignore warnings deba@522: } deba@522: }; deba@522: deba@522: /// \brief \ref named-templ-param "Named parameter" for kpeter@672: /// setting \c PredMap type deba@522: /// deba@522: /// \ref named-templ-param "Named parameter" for setting kpeter@672: /// \c PredMap type. kpeter@672: /// It must meet the \ref concepts::WriteMap "WriteMap" concept, kpeter@672: /// and its value type must be the \c Arc type of the digraph. deba@522: template kpeter@672: struct SetPredMap kpeter@672: : public MinCostArborescence > { deba@522: }; deba@522: deba@522: /// @} deba@522: deba@522: /// \brief Constructor. deba@522: /// kpeter@606: /// \param digraph The digraph the algorithm will run on. kpeter@606: /// \param cost The cost map used by the algorithm. deba@522: MinCostArborescence(const Digraph& digraph, const CostMap& cost) deba@522: : _digraph(&digraph), _cost(&cost), _pred(0), local_pred(false), deba@522: _arborescence(0), local_arborescence(false), deba@522: _arc_order(0), _node_order(0), _cost_arcs(0), deba@522: _heap_cross_ref(0), _heap(0) {} deba@522: deba@522: /// \brief Destructor. deba@522: ~MinCostArborescence() { deba@522: destroyStructures(); deba@522: } deba@522: deba@522: /// \brief Sets the arborescence map. deba@522: /// deba@522: /// Sets the arborescence map. kpeter@606: /// \return (*this) deba@522: MinCostArborescence& arborescenceMap(ArborescenceMap& m) { deba@522: if (local_arborescence) { deba@522: delete _arborescence; deba@522: } deba@522: local_arborescence = false; deba@522: _arborescence = &m; deba@522: return *this; deba@522: } deba@522: kpeter@672: /// \brief Sets the predecessor map. deba@522: /// kpeter@672: /// Sets the predecessor map. kpeter@606: /// \return (*this) deba@522: MinCostArborescence& predMap(PredMap& m) { deba@522: if (local_pred) { deba@522: delete _pred; deba@522: } deba@522: local_pred = false; deba@522: _pred = &m; deba@522: return *this; deba@522: } deba@522: kpeter@631: /// \name Execution Control deba@522: /// The simplest way to execute the algorithm is to use deba@522: /// one of the member functions called \c run(...). \n deba@522: /// If you need more control on the execution, deba@522: /// first you must call \ref init(), then you can add several deba@522: /// source nodes with \ref addSource(). deba@522: /// Finally \ref start() will perform the arborescence deba@522: /// computation. deba@522: deba@522: ///@{ deba@522: deba@522: /// \brief Initializes the internal data structures. deba@522: /// deba@522: /// Initializes the internal data structures. deba@522: /// deba@522: void init() { deba@522: createStructures(); deba@522: _heap->clear(); deba@522: for (NodeIt it(*_digraph); it != INVALID; ++it) { deba@522: (*_cost_arcs)[it].arc = INVALID; kpeter@628: (*_node_order)[it] = -3; kpeter@628: (*_heap_cross_ref)[it] = Heap::PRE_HEAP; deba@522: _pred->set(it, INVALID); deba@522: } deba@522: for (ArcIt it(*_digraph); it != INVALID; ++it) { deba@522: _arborescence->set(it, false); kpeter@628: (*_arc_order)[it] = -1; deba@522: } deba@522: _dual_node_list.clear(); deba@522: _dual_variables.clear(); deba@522: } deba@522: deba@522: /// \brief Adds a new source node. deba@522: /// deba@522: /// Adds a new source node to the algorithm. deba@522: void addSource(Node source) { deba@522: std::vector nodes; deba@522: nodes.push_back(source); deba@522: while (!nodes.empty()) { deba@522: Node node = nodes.back(); deba@522: nodes.pop_back(); deba@522: for (OutArcIt it(*_digraph, node); it != INVALID; ++it) { deba@522: Node target = _digraph->target(it); deba@522: if ((*_node_order)[target] == -3) { deba@522: (*_node_order)[target] = -2; deba@522: nodes.push_back(target); deba@522: queue.push_back(target); deba@522: } deba@522: } deba@522: } deba@522: (*_node_order)[source] = -1; deba@522: } deba@522: deba@522: /// \brief Processes the next node in the priority queue. deba@522: /// deba@522: /// Processes the next node in the priority queue. deba@522: /// deba@522: /// \return The processed node. deba@522: /// kpeter@672: /// \warning The queue must not be empty. deba@522: Node processNextNode() { deba@522: Node node = queue.back(); deba@522: queue.pop_back(); deba@522: if ((*_node_order)[node] == -2) { deba@522: Arc arc = prepare(node); deba@522: Node source = _digraph->source(arc); deba@522: while ((*_node_order)[source] != -1) { deba@522: if ((*_node_order)[source] >= 0) { deba@522: arc = contract(source); deba@522: } else { deba@522: arc = prepare(source); deba@522: } deba@522: source = _digraph->source(arc); deba@522: } deba@522: finalize(arc); deba@522: level_stack.clear(); deba@522: } deba@522: return node; deba@522: } deba@522: deba@522: /// \brief Returns the number of the nodes to be processed. deba@522: /// kpeter@672: /// Returns the number of the nodes to be processed in the priority kpeter@672: /// queue. deba@522: int queueSize() const { deba@522: return queue.size(); deba@522: } deba@522: deba@522: /// \brief Returns \c false if there are nodes to be processed. deba@522: /// deba@522: /// Returns \c false if there are nodes to be processed. deba@522: bool emptyQueue() const { deba@522: return queue.empty(); deba@522: } deba@522: deba@522: /// \brief Executes the algorithm. deba@522: /// deba@522: /// Executes the algorithm. deba@522: /// deba@522: /// \pre init() must be called and at least one node should be added deba@522: /// with addSource() before using this function. deba@522: /// deba@522: ///\note mca.start() is just a shortcut of the following code. deba@522: ///\code deba@522: ///while (!mca.emptyQueue()) { deba@522: /// mca.processNextNode(); deba@522: ///} deba@522: ///\endcode deba@522: void start() { deba@522: while (!emptyQueue()) { deba@522: processNextNode(); deba@522: } deba@522: } deba@522: deba@522: /// \brief Runs %MinCostArborescence algorithm from node \c s. deba@522: /// deba@522: /// This method runs the %MinCostArborescence algorithm from deba@522: /// a root node \c s. deba@522: /// deba@522: /// \note mca.run(s) is just a shortcut of the following code. deba@522: /// \code deba@522: /// mca.init(); deba@522: /// mca.addSource(s); deba@522: /// mca.start(); deba@522: /// \endcode kpeter@672: void run(Node s) { deba@522: init(); kpeter@672: addSource(s); deba@522: start(); deba@522: } deba@522: deba@522: ///@} deba@522: kpeter@672: /// \name Query Functions kpeter@672: /// The result of the %MinCostArborescence algorithm can be obtained kpeter@672: /// using these functions.\n kpeter@672: /// Either run() or start() must be called before using them. kpeter@672: kpeter@672: /// @{ kpeter@672: kpeter@672: /// \brief Returns the cost of the arborescence. kpeter@672: /// kpeter@672: /// Returns the cost of the arborescence. kpeter@672: Value arborescenceCost() const { kpeter@672: Value sum = 0; kpeter@672: for (ArcIt it(*_digraph); it != INVALID; ++it) { kpeter@672: if (arborescence(it)) { kpeter@672: sum += (*_cost)[it]; kpeter@672: } kpeter@672: } kpeter@672: return sum; kpeter@672: } kpeter@672: kpeter@672: /// \brief Returns \c true if the arc is in the arborescence. kpeter@672: /// kpeter@672: /// Returns \c true if the given arc is in the arborescence. kpeter@672: /// \param arc An arc of the digraph. kpeter@672: /// \pre \ref run() must be called before using this function. kpeter@672: bool arborescence(Arc arc) const { kpeter@672: return (*_pred)[_digraph->target(arc)] == arc; kpeter@672: } kpeter@672: kpeter@672: /// \brief Returns a const reference to the arborescence map. kpeter@672: /// kpeter@672: /// Returns a const reference to the arborescence map. kpeter@672: /// \pre \ref run() must be called before using this function. kpeter@672: const ArborescenceMap& arborescenceMap() const { kpeter@672: return *_arborescence; kpeter@672: } kpeter@672: kpeter@672: /// \brief Returns the predecessor arc of the given node. kpeter@672: /// kpeter@672: /// Returns the predecessor arc of the given node. kpeter@672: /// \pre \ref run() must be called before using this function. kpeter@672: Arc pred(Node node) const { kpeter@672: return (*_pred)[node]; kpeter@672: } kpeter@672: kpeter@672: /// \brief Returns a const reference to the pred map. kpeter@672: /// kpeter@672: /// Returns a const reference to the pred map. kpeter@672: /// \pre \ref run() must be called before using this function. kpeter@672: const PredMap& predMap() const { kpeter@672: return *_pred; kpeter@672: } kpeter@672: kpeter@672: /// \brief Indicates that a node is reachable from the sources. kpeter@672: /// kpeter@672: /// Indicates that a node is reachable from the sources. kpeter@672: bool reached(Node node) const { kpeter@672: return (*_node_order)[node] != -3; kpeter@672: } kpeter@672: kpeter@672: /// \brief Indicates that a node is processed. kpeter@672: /// kpeter@672: /// Indicates that a node is processed. The arborescence path exists kpeter@672: /// from the source to the given node. kpeter@672: bool processed(Node node) const { kpeter@672: return (*_node_order)[node] == -1; kpeter@672: } kpeter@672: kpeter@672: /// \brief Returns the number of the dual variables in basis. kpeter@672: /// kpeter@672: /// Returns the number of the dual variables in basis. kpeter@672: int dualNum() const { kpeter@672: return _dual_variables.size(); kpeter@672: } kpeter@672: kpeter@672: /// \brief Returns the value of the dual solution. kpeter@672: /// kpeter@672: /// Returns the value of the dual solution. It should be kpeter@672: /// equal to the arborescence value. kpeter@672: Value dualValue() const { kpeter@672: Value sum = 0; kpeter@672: for (int i = 0; i < int(_dual_variables.size()); ++i) { kpeter@672: sum += _dual_variables[i].value; kpeter@672: } kpeter@672: return sum; kpeter@672: } kpeter@672: kpeter@672: /// \brief Returns the number of the nodes in the dual variable. kpeter@672: /// kpeter@672: /// Returns the number of the nodes in the dual variable. kpeter@672: int dualSize(int k) const { kpeter@672: return _dual_variables[k].end - _dual_variables[k].begin; kpeter@672: } kpeter@672: kpeter@672: /// \brief Returns the value of the dual variable. kpeter@672: /// kpeter@672: /// Returns the the value of the dual variable. kpeter@672: Value dualValue(int k) const { kpeter@672: return _dual_variables[k].value; kpeter@672: } kpeter@672: kpeter@672: /// \brief LEMON iterator for getting a dual variable. kpeter@672: /// kpeter@672: /// This class provides a common style LEMON iterator for getting a kpeter@672: /// dual variable of \ref MinCostArborescence algorithm. kpeter@672: /// It iterates over a subset of the nodes. kpeter@672: class DualIt { kpeter@672: public: kpeter@672: kpeter@672: /// \brief Constructor. kpeter@672: /// kpeter@672: /// Constructor for getting the nodeset of the dual variable kpeter@672: /// of \ref MinCostArborescence algorithm. kpeter@672: DualIt(const MinCostArborescence& algorithm, int variable) kpeter@672: : _algorithm(&algorithm) kpeter@672: { kpeter@672: _index = _algorithm->_dual_variables[variable].begin; kpeter@672: _last = _algorithm->_dual_variables[variable].end; kpeter@672: } kpeter@672: kpeter@672: /// \brief Conversion to \c Node. kpeter@672: /// kpeter@672: /// Conversion to \c Node. kpeter@672: operator Node() const { kpeter@672: return _algorithm->_dual_node_list[_index]; kpeter@672: } kpeter@672: kpeter@672: /// \brief Increment operator. kpeter@672: /// kpeter@672: /// Increment operator. kpeter@672: DualIt& operator++() { kpeter@672: ++_index; kpeter@672: return *this; kpeter@672: } kpeter@672: kpeter@672: /// \brief Validity checking kpeter@672: /// kpeter@672: /// Checks whether the iterator is invalid. kpeter@672: bool operator==(Invalid) const { kpeter@672: return _index == _last; kpeter@672: } kpeter@672: kpeter@672: /// \brief Validity checking kpeter@672: /// kpeter@672: /// Checks whether the iterator is valid. kpeter@672: bool operator!=(Invalid) const { kpeter@672: return _index != _last; kpeter@672: } kpeter@672: kpeter@672: private: kpeter@672: const MinCostArborescence* _algorithm; kpeter@672: int _index, _last; kpeter@672: }; kpeter@672: kpeter@672: /// @} kpeter@672: deba@522: }; deba@522: deba@522: /// \ingroup spantree deba@522: /// deba@522: /// \brief Function type interface for MinCostArborescence algorithm. deba@522: /// deba@522: /// Function type interface for MinCostArborescence algorithm. kpeter@672: /// \param digraph The digraph the algorithm runs on. kpeter@672: /// \param cost An arc map storing the costs. kpeter@672: /// \param source The source node of the arborescence. kpeter@672: /// \retval arborescence An arc map with \c bool (or convertible) value kpeter@672: /// type that stores the arborescence. kpeter@672: /// \return The total cost of the arborescence. deba@522: /// deba@522: /// \sa MinCostArborescence deba@522: template deba@522: typename CostMap::Value minCostArborescence(const Digraph& digraph, deba@522: const CostMap& cost, deba@522: typename Digraph::Node source, deba@522: ArborescenceMap& arborescence) { deba@522: typename MinCostArborescence kpeter@672: ::template SetArborescenceMap deba@522: ::Create mca(digraph, cost); deba@522: mca.arborescenceMap(arborescence); deba@522: mca.run(source); kpeter@672: return mca.arborescenceCost(); deba@522: } deba@522: deba@522: } deba@522: deba@522: #endif