Fix wrong iteration in ListGraph snapshot, part II. (#598)
1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2013
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_MAX_CARDINALITY_SEARCH_H
20 #define LEMON_MAX_CARDINALITY_SEARCH_H
25 /// \brief Maximum cardinality search in undirected digraphs.
27 #include <lemon/bin_heap.h>
28 #include <lemon/bucket_heap.h>
30 #include <lemon/error.h>
31 #include <lemon/maps.h>
37 /// \brief Default traits class of MaxCardinalitySearch class.
39 /// Default traits class of MaxCardinalitySearch class.
40 /// \param Digraph Digraph type.
41 /// \param CapacityMap Type of capacity map.
42 template <typename GR, typename CAP>
43 struct MaxCardinalitySearchDefaultTraits {
44 /// The digraph type the algorithm runs on.
47 template <typename CM>
48 struct CapMapSelector {
50 typedef CM CapacityMap;
52 static CapacityMap *createCapacityMap(const Digraph& g) {
53 return new CapacityMap(g);
57 template <typename CM>
58 struct CapMapSelector<ConstMap<CM, Const<int, 1> > > {
60 typedef ConstMap<CM, Const<int, 1> > CapacityMap;
62 static CapacityMap *createCapacityMap(const Digraph&) {
63 return new CapacityMap;
67 /// \brief The type of the map that stores the arc capacities.
69 /// The type of the map that stores the arc capacities.
70 /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
71 typedef typename CapMapSelector<CAP>::CapacityMap CapacityMap;
73 /// \brief The type of the capacity of the arcs.
74 typedef typename CapacityMap::Value Value;
76 /// \brief Instantiates a CapacityMap.
78 /// This function instantiates a \ref CapacityMap.
79 /// \param digraph is the digraph, to which we would like to define
81 static CapacityMap *createCapacityMap(const Digraph& digraph) {
82 return CapMapSelector<CapacityMap>::createCapacityMap(digraph);
85 /// \brief The cross reference type used by heap.
87 /// The cross reference type used by heap.
88 /// Usually it is \c Digraph::NodeMap<int>.
89 typedef typename Digraph::template NodeMap<int> HeapCrossRef;
91 /// \brief Instantiates a HeapCrossRef.
93 /// This function instantiates a \ref HeapCrossRef.
94 /// \param digraph is the digraph, to which we would like to define the
96 static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
97 return new HeapCrossRef(digraph);
100 template <typename CapacityMap>
101 struct HeapSelector {
102 template <typename Value, typename Ref>
104 typedef BinHeap<Value, Ref, std::greater<Value> > Heap;
108 template <typename CapacityKey>
109 struct HeapSelector<ConstMap<CapacityKey, Const<int, 1> > > {
110 template <typename Value, typename Ref>
112 typedef BucketHeap<Ref, false > Heap;
116 /// \brief The heap type used by MaxCardinalitySearch algorithm.
118 /// The heap type used by MaxCardinalitySearch algorithm. It should
119 /// maximalize the priorities. The default heap type is
120 /// the \ref BinHeap, but it is specialized when the
121 /// CapacityMap is ConstMap<Digraph::Node, Const<int, 1> >
124 /// \sa MaxCardinalitySearch
125 typedef typename HeapSelector<CapacityMap>
126 ::template Selector<Value, HeapCrossRef>
129 /// \brief Instantiates a Heap.
131 /// This function instantiates a \ref Heap.
132 /// \param crossref The cross reference of the heap.
133 static Heap *createHeap(HeapCrossRef& crossref) {
134 return new Heap(crossref);
137 /// \brief The type of the map that stores whether a node is processed.
139 /// The type of the map that stores whether a node is processed.
140 /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
141 /// By default it is a NullMap.
142 typedef NullMap<typename Digraph::Node, bool> ProcessedMap;
144 /// \brief Instantiates a ProcessedMap.
146 /// This function instantiates a \ref ProcessedMap.
147 /// \param digraph is the digraph, to which
148 /// we would like to define the \ref ProcessedMap
150 static ProcessedMap *createProcessedMap(const Digraph &digraph)
152 static ProcessedMap *createProcessedMap(const Digraph &)
155 return new ProcessedMap();
158 /// \brief The type of the map that stores the cardinalities of the nodes.
160 /// The type of the map that stores the cardinalities of the nodes.
161 /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
162 typedef typename Digraph::template NodeMap<Value> CardinalityMap;
164 /// \brief Instantiates a CardinalityMap.
166 /// This function instantiates a \ref CardinalityMap.
167 /// \param digraph is the digraph, to which we would like to
168 /// define the \ref CardinalityMap
169 static CardinalityMap *createCardinalityMap(const Digraph &digraph) {
170 return new CardinalityMap(digraph);
178 /// \brief Maximum Cardinality Search algorithm class.
180 /// This class provides an efficient implementation of Maximum Cardinality
181 /// Search algorithm. The maximum cardinality search first chooses any
182 /// node of the digraph. Then every time it chooses one unprocessed node
183 /// with maximum cardinality, i.e the sum of capacities on out arcs
185 /// which were previusly processed.
186 /// If there is a cut in the digraph the algorithm should choose
187 /// again any unprocessed node of the digraph.
189 /// The arc capacities are passed to the algorithm using a
190 /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
191 /// kind of capacity.
193 /// The type of the capacity is determined by the \ref
194 /// concepts::ReadMap::Value "Value" of the capacity map.
196 /// It is also possible to change the underlying priority heap.
199 /// \param GR The digraph type the algorithm runs on. The value of
200 /// Digraph is not used directly by the search algorithm, it
201 /// is only passed to \ref MaxCardinalitySearchDefaultTraits.
202 /// \param CAP This read-only ArcMap determines the capacities of
203 /// the arcs. It is read once for each arc, so the map may involve in
204 /// relatively time consuming process to compute the arc capacity if
205 /// it is necessary. The default map type is \ref
206 /// ConstMap "ConstMap<concepts::Digraph::Arc, Const<int,1> >". The value
207 /// of CapacityMap is not used directly by search algorithm, it is only
208 /// passed to \ref MaxCardinalitySearchDefaultTraits.
209 /// \param TR Traits class to set various data types used by the
210 /// algorithm. The default traits class is
211 /// \ref MaxCardinalitySearchDefaultTraits
212 /// "MaxCardinalitySearchDefaultTraits<GR, CAP>".
213 /// See \ref MaxCardinalitySearchDefaultTraits
214 /// for the documentation of a MaxCardinalitySearch traits class.
217 template <typename GR, typename CAP, typename TR>
219 template <typename GR, typename CAP =
220 ConstMap<typename GR::Arc, Const<int,1> >,
222 MaxCardinalitySearchDefaultTraits<GR, CAP> >
224 class MaxCardinalitySearch {
228 ///The type of the underlying digraph.
229 typedef typename Traits::Digraph Digraph;
231 ///The type of the capacity of the arcs.
232 typedef typename Traits::CapacityMap::Value Value;
233 ///The type of the map that stores the arc capacities.
234 typedef typename Traits::CapacityMap CapacityMap;
235 ///The type of the map indicating if a node is processed.
236 typedef typename Traits::ProcessedMap ProcessedMap;
237 ///The type of the map that stores the cardinalities of the nodes.
238 typedef typename Traits::CardinalityMap CardinalityMap;
239 ///The cross reference type used for the current heap.
240 typedef typename Traits::HeapCrossRef HeapCrossRef;
241 ///The heap type used by the algorithm. It maximizes the priorities.
242 typedef typename Traits::Heap Heap;
244 // Pointer to the underlying digraph.
245 const Digraph *_graph;
246 // Pointer to the capacity map
247 const CapacityMap *_capacity;
248 // Indicates if \ref _capacity is locally allocated (\c true) or not.
250 // Pointer to the map of cardinality.
251 CardinalityMap *_cardinality;
252 // Indicates if \ref _cardinality is locally allocated (\c true) or not.
253 bool local_cardinality;
254 // Pointer to the map of processed status of the nodes.
255 ProcessedMap *_processed;
256 // Indicates if \ref _processed is locally allocated (\c true) or not.
257 bool local_processed;
258 // Pointer to the heap cross references.
259 HeapCrossRef *_heap_cross_ref;
260 // Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not.
261 bool local_heap_cross_ref;
262 // Pointer to the heap.
264 // Indicates if \ref _heap is locally allocated (\c true) or not.
269 typedef MaxCardinalitySearch Create;
271 ///\name Named template parameters
276 struct DefCapacityMapTraits : public Traits {
277 typedef T CapacityMap;
278 static CapacityMap *createCapacityMap(const Digraph &) {
279 LEMON_ASSERT(false,"Uninitialized parameter.");
283 /// \brief \ref named-templ-param "Named parameter" for setting
286 /// \ref named-templ-param "Named parameter" for setting CapacityMap type
287 /// for the algorithm.
289 struct SetCapacityMap
290 : public MaxCardinalitySearch<Digraph, CapacityMap,
291 DefCapacityMapTraits<T> > {
292 typedef MaxCardinalitySearch<Digraph, CapacityMap,
293 DefCapacityMapTraits<T> > Create;
297 struct DefCardinalityMapTraits : public Traits {
298 typedef T CardinalityMap;
299 static CardinalityMap *createCardinalityMap(const Digraph &)
301 LEMON_ASSERT(false,"Uninitialized parameter.");
305 /// \brief \ref named-templ-param "Named parameter" for setting
306 /// CardinalityMap type
308 /// \ref named-templ-param "Named parameter" for setting CardinalityMap
309 /// type for the algorithm.
311 struct SetCardinalityMap
312 : public MaxCardinalitySearch<Digraph, CapacityMap,
313 DefCardinalityMapTraits<T> > {
314 typedef MaxCardinalitySearch<Digraph, CapacityMap,
315 DefCardinalityMapTraits<T> > Create;
319 struct DefProcessedMapTraits : public Traits {
320 typedef T ProcessedMap;
321 static ProcessedMap *createProcessedMap(const Digraph &) {
322 LEMON_ASSERT(false,"Uninitialized parameter.");
326 /// \brief \ref named-templ-param "Named parameter" for setting
327 /// ProcessedMap type
329 /// \ref named-templ-param "Named parameter" for setting ProcessedMap type
330 /// for the algorithm.
332 struct SetProcessedMap
333 : public MaxCardinalitySearch<Digraph, CapacityMap,
334 DefProcessedMapTraits<T> > {
335 typedef MaxCardinalitySearch<Digraph, CapacityMap,
336 DefProcessedMapTraits<T> > Create;
339 template <class H, class CR>
340 struct DefHeapTraits : public Traits {
341 typedef CR HeapCrossRef;
343 static HeapCrossRef *createHeapCrossRef(const Digraph &) {
344 LEMON_ASSERT(false,"Uninitialized parameter.");
347 static Heap *createHeap(HeapCrossRef &) {
348 LEMON_ASSERT(false,"Uninitialized parameter.");
352 /// \brief \ref named-templ-param "Named parameter" for setting heap
353 /// and cross reference type
355 /// \ref named-templ-param "Named parameter" for setting heap and cross
356 /// reference type for the algorithm.
357 template <class H, class CR = typename Digraph::template NodeMap<int> >
359 : public MaxCardinalitySearch<Digraph, CapacityMap,
360 DefHeapTraits<H, CR> > {
361 typedef MaxCardinalitySearch< Digraph, CapacityMap,
362 DefHeapTraits<H, CR> > Create;
365 template <class H, class CR>
366 struct DefStandardHeapTraits : public Traits {
367 typedef CR HeapCrossRef;
369 static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
370 return new HeapCrossRef(digraph);
372 static Heap *createHeap(HeapCrossRef &crossref) {
373 return new Heap(crossref);
377 /// \brief \ref named-templ-param "Named parameter" for setting heap and
378 /// cross reference type with automatic allocation
380 /// \ref named-templ-param "Named parameter" for setting heap and cross
381 /// reference type. It can allocate the heap and the cross reference
382 /// object if the cross reference's constructor waits for the digraph as
383 /// parameter and the heap's constructor waits for the cross reference.
384 template <class H, class CR = typename Digraph::template NodeMap<int> >
385 struct SetStandardHeap
386 : public MaxCardinalitySearch<Digraph, CapacityMap,
387 DefStandardHeapTraits<H, CR> > {
388 typedef MaxCardinalitySearch<Digraph, CapacityMap,
389 DefStandardHeapTraits<H, CR> >
398 MaxCardinalitySearch() {}
402 /// \brief Constructor.
404 ///\param digraph the digraph the algorithm will run on.
405 ///\param capacity the capacity map used by the algorithm.
406 MaxCardinalitySearch(const Digraph& digraph,
407 const CapacityMap& capacity) :
409 _capacity(&capacity), local_capacity(false),
410 _cardinality(0), local_cardinality(false),
411 _processed(0), local_processed(false),
412 _heap_cross_ref(0), local_heap_cross_ref(false),
413 _heap(0), local_heap(false)
416 /// \brief Constructor.
418 ///\param digraph the digraph the algorithm will run on.
420 ///A constant 1 capacity map will be allocated.
421 MaxCardinalitySearch(const Digraph& digraph) :
423 _capacity(0), local_capacity(false),
424 _cardinality(0), local_cardinality(false),
425 _processed(0), local_processed(false),
426 _heap_cross_ref(0), local_heap_cross_ref(false),
427 _heap(0), local_heap(false)
430 /// \brief Destructor.
431 ~MaxCardinalitySearch() {
432 if(local_capacity) delete _capacity;
433 if(local_cardinality) delete _cardinality;
434 if(local_processed) delete _processed;
435 if(local_heap_cross_ref) delete _heap_cross_ref;
436 if(local_heap) delete _heap;
439 /// \brief Sets the capacity map.
441 /// Sets the capacity map.
442 /// \return <tt> (*this) </tt>
443 MaxCardinalitySearch &capacityMap(const CapacityMap &m) {
444 if (local_capacity) {
446 local_capacity=false;
452 /// \brief Returns a const reference to the capacity map.
454 /// Returns a const reference to the capacity map used by
456 const CapacityMap &capacityMap() const {
460 /// \brief Sets the map storing the cardinalities calculated by the
463 /// Sets the map storing the cardinalities calculated by the algorithm.
464 /// If you don't use this function before calling \ref run(),
465 /// it will allocate one. The destuctor deallocates this
466 /// automatically allocated map, of course.
467 /// \return <tt> (*this) </tt>
468 MaxCardinalitySearch &cardinalityMap(CardinalityMap &m) {
469 if(local_cardinality) {
471 local_cardinality=false;
477 /// \brief Sets the map storing the processed nodes.
479 /// Sets the map storing the processed nodes.
480 /// If you don't use this function before calling \ref run(),
481 /// it will allocate one. The destuctor deallocates this
482 /// automatically allocated map, of course.
483 /// \return <tt> (*this) </tt>
484 MaxCardinalitySearch &processedMap(ProcessedMap &m)
486 if(local_processed) {
488 local_processed=false;
494 /// \brief Returns a const reference to the cardinality map.
496 /// Returns a const reference to the cardinality map used by
498 const ProcessedMap &processedMap() const {
502 /// \brief Sets the heap and the cross reference used by algorithm.
504 /// Sets the heap and the cross reference used by algorithm.
505 /// If you don't use this function before calling \ref run(),
506 /// it will allocate one. The destuctor deallocates this
507 /// automatically allocated map, of course.
508 /// \return <tt> (*this) </tt>
509 MaxCardinalitySearch &heap(Heap& hp, HeapCrossRef &cr) {
510 if(local_heap_cross_ref) {
511 delete _heap_cross_ref;
512 local_heap_cross_ref = false;
514 _heap_cross_ref = &cr;
523 /// \brief Returns a const reference to the heap.
525 /// Returns a const reference to the heap used by
527 const Heap &heap() const {
531 /// \brief Returns a const reference to the cross reference.
533 /// Returns a const reference to the cross reference
535 const HeapCrossRef &heapCrossRef() const {
536 return *_heap_cross_ref;
541 typedef typename Digraph::Node Node;
542 typedef typename Digraph::NodeIt NodeIt;
543 typedef typename Digraph::Arc Arc;
544 typedef typename Digraph::InArcIt InArcIt;
548 local_capacity = true;
549 _capacity = Traits::createCapacityMap(*_graph);
552 local_cardinality = true;
553 _cardinality = Traits::createCardinalityMap(*_graph);
556 local_processed = true;
557 _processed = Traits::createProcessedMap(*_graph);
559 if (!_heap_cross_ref) {
560 local_heap_cross_ref = true;
561 _heap_cross_ref = Traits::createHeapCrossRef(*_graph);
565 _heap = Traits::createHeap(*_heap_cross_ref);
569 void finalizeNodeData(Node node, Value capacity) {
570 _processed->set(node, true);
571 _cardinality->set(node, capacity);
575 /// \name Execution control
576 /// The simplest way to execute the algorithm is to use
577 /// one of the member functions called \ref run().
579 /// If you need more control on the execution,
580 /// first you must call \ref init(), then you can add several source nodes
581 /// with \ref addSource().
582 /// Finally \ref start() will perform the computation.
586 /// \brief Initializes the internal data structures.
588 /// Initializes the internal data structures, and clears the heap.
592 for (NodeIt it(*_graph) ; it != INVALID ; ++it) {
593 _processed->set(it, false);
594 _heap_cross_ref->set(it, Heap::PRE_HEAP);
598 /// \brief Adds a new source node.
600 /// Adds a new source node to the priority heap.
602 /// It checks if the node has not yet been added to the heap.
603 void addSource(Node source, Value capacity = 0) {
604 if(_heap->state(source) == Heap::PRE_HEAP) {
605 _heap->push(source, capacity);
609 /// \brief Processes the next node in the priority heap
611 /// Processes the next node in the priority heap.
613 /// \return The processed node.
615 /// \warning The priority heap must not be empty!
616 Node processNextNode() {
617 Node node = _heap->top();
618 finalizeNodeData(node, _heap->prio());
621 for (InArcIt it(*_graph, node); it != INVALID; ++it) {
622 Node source = _graph->source(it);
623 switch (_heap->state(source)) {
625 _heap->push(source, (*_capacity)[it]);
628 _heap->decrease(source, (*_heap)[source] + (*_capacity)[it]);
630 case Heap::POST_HEAP:
637 /// \brief Next node to be processed.
639 /// Next node to be processed.
641 /// \return The next node to be processed or INVALID if the
642 /// priority heap is empty.
644 return !_heap->empty() ? _heap->top() : INVALID;
647 /// \brief Returns \c false if there are nodes
648 /// to be processed in the priority heap
650 /// Returns \c false if there are nodes
651 /// to be processed in the priority heap
652 bool emptyQueue() { return _heap->empty(); }
653 /// \brief Returns the number of the nodes to be processed
654 /// in the priority heap
656 /// Returns the number of the nodes to be processed in the priority heap
657 int emptySize() { return _heap->size(); }
659 /// \brief Executes the algorithm.
661 /// Executes the algorithm.
663 ///\pre init() must be called and at least one node should be added
664 /// with addSource() before using this function.
666 /// This method runs the Maximum Cardinality Search algorithm from the
669 while ( !_heap->empty() ) processNextNode();
672 /// \brief Executes the algorithm until \c dest is reached.
674 /// Executes the algorithm until \c dest is reached.
676 /// \pre init() must be called and at least one node should be added
677 /// with addSource() before using this function.
679 /// This method runs the %MaxCardinalitySearch algorithm from the source
681 void start(Node dest) {
682 while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
683 if ( !_heap->empty() ) finalizeNodeData(_heap->top(), _heap->prio());
686 /// \brief Executes the algorithm until a condition is met.
688 /// Executes the algorithm until a condition is met.
690 /// \pre init() must be called and at least one node should be added
691 /// with addSource() before using this function.
693 /// \param nm must be a bool (or convertible) node map. The algorithm
694 /// will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
695 template <typename NodeBoolMap>
696 void start(const NodeBoolMap &nm) {
697 while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
698 if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
701 /// \brief Runs the maximum cardinality search algorithm from node \c s.
703 /// This method runs the %MaxCardinalitySearch algorithm from a root
706 ///\note d.run(s) is just a shortcut of the following code.
718 /// \brief Runs the maximum cardinality search algorithm for the
721 /// This method runs the %MaxCardinalitySearch algorithm from all
722 /// unprocessed node of the digraph.
724 ///\note d.run(s) is just a shortcut of the following code.
727 /// for (NodeIt it(digraph); it != INVALID; ++it) {
728 /// if (!d.reached(it)) {
736 for (NodeIt it(*_graph); it != INVALID; ++it) {
746 /// \name Query Functions
747 /// The results of the maximum cardinality search algorithm can be
748 /// obtained using these functions.
750 /// Before the use of these functions, either run() or start() must be
755 /// \brief The cardinality of a node.
757 /// Returns the cardinality of a node.
758 /// \pre \ref run() must be called before using this function.
759 /// \warning If node \c v in unreachable from the root the return value
760 /// of this funcion is undefined.
761 Value cardinality(Node node) const { return (*_cardinality)[node]; }
763 /// \brief The current cardinality of a node.
765 /// Returns the current cardinality of a node.
766 /// \pre the given node should be reached but not processed
767 Value currentCardinality(Node node) const { return (*_heap)[node]; }
769 /// \brief Returns a reference to the NodeMap of cardinalities.
771 /// Returns a reference to the NodeMap of cardinalities. \pre \ref run()
772 /// must be called before using this function.
773 const CardinalityMap &cardinalityMap() const { return *_cardinality;}
775 /// \brief Checks if a node is reachable from the root.
777 /// Returns \c true if \c v is reachable from the root.
778 /// \warning The source nodes are initated as unreached.
779 /// \pre \ref run() must be called before using this function.
780 bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; }
782 /// \brief Checks if a node is processed.
784 /// Returns \c true if \c v is processed, i.e. the shortest
785 /// path to \c v has already found.
786 /// \pre \ref run() must be called before using this function.
787 bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_HEAP; }