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