3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_MIN_COST_ARBORESCENCE_H
20 #define LEMON_MIN_COST_ARBORESCENCE_H
24 ///\brief Minimum Cost Arborescence algorithm.
28 #include <lemon/list_graph.h>
33 /// \brief Default traits class of MinCostArborescence class.
35 /// Default traits class of MinCostArborescence class.
36 /// \param _Graph Graph type.
37 /// \param _CostMap Type of cost map.
38 template <class _Graph, class _CostMap>
39 struct MinCostArborescenceDefaultTraits{
41 /// \brief The graph type the algorithm runs on.
44 /// \brief The type of the map that stores the edge costs.
46 /// The type of the map that stores the edge costs.
47 /// It must meet the \ref concept::ReadMap "ReadMap" concept.
48 typedef _CostMap CostMap;
50 /// \brief The value type of the costs.
52 /// The value type of the costs.
53 typedef typename CostMap::Value Value;
55 /// \brief The type of the map that stores which edges are
56 /// in the arborescence.
58 /// The type of the map that stores which edges are in the arborescence.
59 /// It must meet the \ref concept::ReadWriteMap "ReadWriteMap" concept.
60 /// Initially it will be setted to false on each edge. The algorithm
61 /// may set each value one time to true and maybe after it to false again.
62 /// Therefore you cannot use maps like BackInserteBoolMap with this
64 typedef typename Graph::template EdgeMap<bool> ArborescenceMap;
66 /// \brief Instantiates a ArborescenceMap.
68 /// This function instantiates a \ref ArborescenceMap.
69 /// \param _graph is the graph, to which we would like to define the
71 static ArborescenceMap *createArborescenceMap(const Graph &_graph){
72 return new ArborescenceMap(_graph);
79 /// \brief %MinCostArborescence algorithm class.
81 /// This class provides an efficient implementation of
82 /// %MinCostArborescence algorithm. The arborescence is a tree
83 /// which is directed from a given source node of the graph. One or
84 /// more sources should be given for the algorithm and it will calculate
85 /// the minimum cost subgraph which are union of arborescences with the
86 /// given sources and spans all the nodes which are reachable from the
87 /// sources. The time complexity of the algorithm is O(n^2 + e).
89 /// \param _Graph The graph type the algorithm runs on. The default value
90 /// is \ref ListGraph. The value of _Graph is not used directly by
91 /// MinCostArborescence, it is only passed to
92 /// \ref MinCostArborescenceDefaultTraits.
93 /// \param _CostMap This read-only EdgeMap determines the costs of the
94 /// edges. It is read once for each edge, so the map may involve in
95 /// relatively time consuming process to compute the edge cost if
96 /// it is necessary. The default map type is \ref
97 /// concept::StaticGraph::EdgeMap "Graph::EdgeMap<int>". The value
98 /// of _CostMap is not used directly by MinCostArborescence,
99 /// it is only passed to \ref MinCostArborescenceDefaultTraits.
100 /// \param _Traits Traits class to set various data types used
101 /// by the algorithm. The default traits class is
102 /// \ref MinCostArborescenceDefaultTraits
103 /// "MinCostArborescenceDefaultTraits<_Graph,_CostMap>". See \ref
104 /// MinCostArborescenceDefaultTraits for the documentation of a
105 /// MinCostArborescence traits class.
107 /// \author Balazs Dezso
109 template <typename _Graph = ListGraph,
110 typename _CostMap = typename _Graph::template EdgeMap<int>,
112 MinCostArborescenceDefaultTraits<_Graph, _CostMap> >
114 template <typename _Graph, typename _CostMap, typedef _Traits>
116 class MinCostArborescence {
119 /// \brief \ref Exception for uninitialized parameters.
121 /// This error represents problems in the initialization
122 /// of the parameters of the algorithms.
123 class UninitializedParameter : public lemon::UninitializedParameter {
125 virtual const char* exceptionName() const {
126 return "lemon::MinCostArborescence::UninitializedParameter";
131 typedef _Traits Traits;
132 /// The type of the underlying graph.
133 typedef typename Traits::Graph Graph;
134 /// The type of the map that stores the edge costs.
135 typedef typename Traits::CostMap CostMap;
136 ///The type of the costs of the edges.
137 typedef typename Traits::Value Value;
138 ///The type of the map that stores which edges are in the arborescence.
139 typedef typename Traits::ArborescenceMap ArborescenceMap;
143 typedef typename Graph::Node Node;
144 typedef typename Graph::Edge Edge;
145 typedef typename Graph::NodeIt NodeIt;
146 typedef typename Graph::EdgeIt EdgeIt;
147 typedef typename Graph::InEdgeIt InEdgeIt;
148 typedef typename Graph::OutEdgeIt OutEdgeIt;
156 CostEdge(Edge _edge, Value _value) : edge(_edge), value(_value) {}
163 ArborescenceMap* _arborescence_map;
164 bool local_arborescence_map;
166 typedef typename Graph::template NodeMap<int> LevelMap;
169 typedef typename Graph::template NodeMap<CostEdge> CostEdgeMap;
170 CostEdgeMap *_cost_edges;
174 std::vector<CostEdge> edges;
179 std::vector<StackLevel> level_stack;
180 std::vector<Node> queue;
186 /// \name Named template parameters
191 struct DefArborescenceMapTraits : public Traits {
192 typedef T ArborescenceMap;
193 static ArborescenceMap *createArborescenceMap(const Graph &)
195 throw UninitializedParameter();
199 /// \brief \ref named-templ-param "Named parameter" for
200 /// setting ArborescenceMap type
202 /// \ref named-templ-param "Named parameter" for setting
203 /// ArborescenceMap type
205 struct DefArborescenceMap
206 : public MinCostArborescence<Graph, CostMap,
207 DefArborescenceMapTraits<T> > {
208 typedef MinCostArborescence<Graph, CostMap,
209 DefArborescenceMapTraits<T> > Create;
214 /// \brief Constructor.
216 /// \param _graph The graph the algorithm will run on.
217 /// \param _cost The cost map used by the algorithm.
218 MinCostArborescence(const Graph& _graph, const CostMap& _cost)
219 : graph(&_graph), cost(&_cost),
220 _arborescence_map(0), local_arborescence_map(false),
221 _level(0), _cost_edges(0) {}
223 /// \brief Destructor.
224 ~MinCostArborescence() {
228 /// \brief Sets the arborescence map.
230 /// Sets the arborescence map.
231 /// \return \c (*this)
232 MinCostArborescence& arborescenceMap(ArborescenceMap& m) {
233 _arborescence_map = &m;
237 /// \name Query Functions
238 /// The result of the %MinCostArborescence algorithm can be obtained
239 /// using these functions.\n
240 /// Before the use of these functions,
241 /// either run() or start() must be called.
245 /// \brief Returns a reference to the arborescence map.
247 /// Returns a reference to the arborescence map.
248 const ArborescenceMap& arborescenceMap() const {
249 return *_arborescence_map;
252 /// \brief Returns true if the edge is in the arborescence.
254 /// Returns true if the edge is in the arborescence.
255 /// \param edge The edge of the graph.
256 /// \pre \ref run() must be called before using this function.
257 bool arborescenceEdge(Edge edge) const {
258 return (*_arborescence_map)[edge];
261 /// \brief Returns the cost of the arborescence.
263 /// Returns the cost of the arborescence.
264 Value arborescenceCost() const {
266 for (EdgeIt it(*graph); it != INVALID; ++it) {
267 if (arborescenceEdge(it)) {
276 /// \name Execution control
277 /// The simplest way to execute the algorithm is to use
278 /// one of the member functions called \c run(...). \n
279 /// If you need more control on the execution,
280 /// first you must call \ref init(), then you can add several
281 /// source nodes with \ref addSource().
282 /// Finally \ref start() will perform the actual path
287 /// \brief Initializes the internal data structures.
289 /// Initializes the internal data structures.
293 for (NodeIt it(*graph); it != INVALID; ++it) {
294 (*_cost_edges)[it].edge = INVALID;
297 for (EdgeIt it(*graph); it != INVALID; ++it) {
298 _arborescence_map->set(it, false);
302 /// \brief Adds a new source node.
304 /// Adds a new source node to the algorithm.
305 void addSource(Node source) {
306 std::vector<Node> nodes;
307 nodes.push_back(source);
308 while (!nodes.empty()) {
309 Node node = nodes.back();
311 for (OutEdgeIt it(*graph, node); it != INVALID; ++it) {
312 if ((*_level)[graph->target(it)] == -3) {
313 (*_level)[graph->target(it)] = -2;
314 nodes.push_back(graph->target(it));
315 queue.push_back(graph->target(it));
319 (*_level)[source] = -1;
322 /// \brief Processes the next node in the priority queue.
324 /// Processes the next node in the priority queue.
326 /// \return The processed node.
328 /// \warning The queue must not be empty!
329 Node processNextNode() {
331 Node node = queue.back();
333 if ((*_level)[node] == -2) {
334 Edge edge = prepare(node);
335 while ((*_level)[graph->source(edge)] != -1) {
336 if ((*_level)[graph->source(edge)] >= 0) {
337 edge = contract(bottom((*_level)[graph->source(edge)]));
339 edge = prepare(graph->source(edge));
342 finalize(graph->target(edge));
348 /// \brief Returns the number of the nodes to be processed.
350 /// Returns the number of the nodes to be processed.
351 int queueSize() const {
355 /// \brief Returns \c false if there are nodes to be processed.
357 /// Returns \c false if there are nodes to be processed.
358 bool emptyQueue() const {
359 return queue.empty();
362 /// \brief Executes the algorithm.
364 /// Executes the algorithm.
366 /// \pre init() must be called and at least one node should be added
367 /// with addSource() before using this function.
369 ///\note mca.start() is just a shortcut of the following code.
371 ///while (!mca.emptyQueue()) {
372 /// mca.processNextNode();
376 while (!emptyQueue()) {
381 /// \brief Runs %MinCostArborescence algorithm from node \c s.
383 /// This method runs the %MinCostArborescence algorithm from
384 /// a root node \c s.
386 ///\note mca.run(s) is just a shortcut of the following code.
392 void run(Node node) {
402 void initStructures() {
403 if (!_arborescence_map) {
404 local_arborescence_map = true;
405 _arborescence_map = Traits::createArborescenceMap(*graph);
408 _level = new LevelMap(*graph);
411 _cost_edges = new CostEdgeMap(*graph);
415 void destroyStructures() {
422 if (local_arborescence_map) {
423 delete _arborescence_map;
427 Edge prepare(Node node) {
428 std::vector<Node> nodes;
429 (*_level)[node] = node_counter;
430 for (InEdgeIt it(*graph, node); it != INVALID; ++it) {
432 Value value = (*cost)[it];
433 if (graph->source(edge) == node ||
434 (*_level)[graph->source(edge)] == -3) continue;
435 if ((*_cost_edges)[graph->source(edge)].edge == INVALID) {
436 (*_cost_edges)[graph->source(edge)].edge = edge;
437 (*_cost_edges)[graph->source(edge)].value = value;
438 nodes.push_back(graph->source(edge));
440 if ((*_cost_edges)[graph->source(edge)].value > value) {
441 (*_cost_edges)[graph->source(edge)].edge = edge;
442 (*_cost_edges)[graph->source(edge)].value = value;
446 CostEdge minimum = (*_cost_edges)[nodes[0]];
447 for (int i = 1; i < (int)nodes.size(); ++i) {
448 if ((*_cost_edges)[nodes[i]].value < minimum.value) {
449 minimum = (*_cost_edges)[nodes[i]];
453 level.node_level = node_counter;
454 for (int i = 0; i < (int)nodes.size(); ++i) {
455 (*_cost_edges)[nodes[i]].value -= minimum.value;
456 level.edges.push_back((*_cost_edges)[nodes[i]]);
457 (*_cost_edges)[nodes[i]].edge = INVALID;
459 level_stack.push_back(level);
461 _arborescence_map->set(minimum.edge, true);
465 Edge contract(int node_bottom) {
466 std::vector<Node> nodes;
467 while (!level_stack.empty() &&
468 level_stack.back().node_level >= node_bottom) {
469 for (int i = 0; i < (int)level_stack.back().edges.size(); ++i) {
470 Edge edge = level_stack.back().edges[i].edge;
471 Value value = level_stack.back().edges[i].value;
472 if ((*_level)[graph->source(edge)] >= node_bottom) continue;
473 if ((*_cost_edges)[graph->source(edge)].edge == INVALID) {
474 (*_cost_edges)[graph->source(edge)].edge = edge;
475 (*_cost_edges)[graph->source(edge)].value = value;
476 nodes.push_back(graph->source(edge));
478 if ((*_cost_edges)[graph->source(edge)].value > value) {
479 (*_cost_edges)[graph->source(edge)].edge = edge;
480 (*_cost_edges)[graph->source(edge)].value = value;
484 level_stack.pop_back();
486 CostEdge minimum = (*_cost_edges)[nodes[0]];
487 for (int i = 1; i < (int)nodes.size(); ++i) {
488 if ((*_cost_edges)[nodes[i]].value < minimum.value) {
489 minimum = (*_cost_edges)[nodes[i]];
493 level.node_level = node_bottom;
494 for (int i = 0; i < (int)nodes.size(); ++i) {
495 (*_cost_edges)[nodes[i]].value -= minimum.value;
496 level.edges.push_back((*_cost_edges)[nodes[i]]);
497 (*_cost_edges)[nodes[i]].edge = INVALID;
499 level_stack.push_back(level);
500 _arborescence_map->set(minimum.edge, true);
504 int bottom(int level) {
505 int k = level_stack.size() - 1;
506 while (level_stack[k].node_level > level) {
509 return level_stack[k].node_level;
512 void finalize(Node source) {
513 std::vector<Node> nodes;
514 nodes.push_back(source);
515 while (!nodes.empty()) {
516 Node node = nodes.back();
518 for (OutEdgeIt it(*graph, node); it != INVALID; ++it) {
519 if ((*_level)[graph->target(it)] >= 0 && (*_arborescence_map)[it]) {
520 (*_level)[graph->target(it)] = -1;
521 nodes.push_back(graph->target(it));
523 _arborescence_map->set(it, false);
527 (*_level)[source] = -1;
532 /// \ingroup spantree
534 /// \brief Function type interface for MinCostArborescence algorithm.
536 /// Function type interface for MinCostArborescence algorithm.
537 /// \param graph The Graph that the algorithm runs on.
538 /// \param cost The CostMap of the edges.
539 /// \param source The source of the arborescence.
540 /// \retval arborescence The bool EdgeMap which stores the arborescence.
541 /// \return The cost of the arborescence.
543 /// \sa MinCostArborescence
544 template <typename Graph, typename CostMap, typename ArborescenceMap>
545 typename CostMap::Value minCostArborescence(const Graph& graph,
547 typename Graph::Node source,
548 ArborescenceMap& arborescence) {
549 typename MinCostArborescence<Graph, CostMap>
550 ::template DefArborescenceMap<ArborescenceMap>
551 ::Create mca(graph, cost);
552 mca.arborescenceMap(arborescence);
554 return mca.arborescenceCost();