diff --git a/doc/groups.dox b/doc/groups.dox --- a/doc/groups.dox +++ b/doc/groups.dox @@ -226,14 +226,6 @@ */ /** -@defgroup matrices Matrices -@ingroup datas -\brief Two dimensional data storages implemented in LEMON. - -This group contains two dimensional data storages implemented in LEMON. -*/ - -/** @defgroup paths Path Structures @ingroup datas \brief %Path structures implemented in LEMON. @@ -246,7 +238,36 @@ efficient to have e.g. the Dijkstra algorithm to store its result in any kind of path structure. -\sa lemon::concepts::Path +\sa \ref concepts::Path "Path concept" +*/ + +/** +@defgroup heaps Heap Structures +@ingroup datas +\brief %Heap structures implemented in LEMON. + +This group contains the heap structures implemented in LEMON. + +LEMON provides several heap classes. They are efficient implementations +of the abstract data type \e priority \e queue. They store items with +specified values called \e priorities in such a way that finding and +removing the item with minimum priority are efficient. +The basic operations are adding and erasing items, changing the priority +of an item, etc. + +Heaps are crucial in several algorithms, such as Dijkstra and Prim. +The heap implementations have the same interface, thus any of them can be +used easily in such algorithms. + +\sa \ref concepts::Heap "Heap concept" +*/ + +/** +@defgroup matrices Matrices +@ingroup datas +\brief Two dimensional data storages implemented in LEMON. + +This group contains two dimensional data storages implemented in LEMON. */ /** diff --git a/lemon/bin_heap.h b/lemon/bin_heap.h --- a/lemon/bin_heap.h +++ b/lemon/bin_heap.h @@ -19,9 +19,9 @@ #ifndef LEMON_BIN_HEAP_H #define LEMON_BIN_HEAP_H -///\ingroup auxdat +///\ingroup heaps ///\file -///\brief Binary Heap implementation. +///\brief Binary heap implementation. #include #include @@ -29,45 +29,41 @@ namespace lemon { - ///\ingroup auxdat + /// \ingroup heaps /// - ///\brief A Binary Heap implementation. + /// \brief Binary heap data structure. /// - ///This class implements the \e binary \e heap data structure. + /// This class implements the \e binary \e heap data structure. + /// It fully conforms to the \ref concepts::Heap "heap concept". /// - ///A \e heap is a data structure for storing items with specified values - ///called \e priorities in such a way that finding the item with minimum - ///priority is efficient. \c CMP specifies the ordering of the priorities. - ///In a heap one can change the priority of an item, add or erase an - ///item, etc. - /// - ///\tparam PR Type of the priority of the items. - ///\tparam IM A read and writable item map with int values, used internally - ///to handle the cross references. - ///\tparam CMP A functor class for the ordering of the priorities. - ///The default is \c std::less. - /// - ///\sa FibHeap - ///\sa Dijkstra + /// \tparam PR Type of the priorities of the items. + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam CMP A functor class for comparing the priorities. + /// The default is \c std::less. +#ifdef DOXYGEN + template +#else template > +#endif class BinHeap { + public: - public: - ///\e + /// Type of the item-int map. typedef IM ItemIntMap; - ///\e + /// Type of the priorities. typedef PR Prio; - ///\e + /// Type of the items stored in the heap. typedef typename ItemIntMap::Key Item; - ///\e + /// Type of the item-priority pairs. typedef std::pair Pair; - ///\e + /// Functor type for comparing the priorities. typedef CMP Compare; - /// \brief Type to represent the items states. + /// \brief Type to represent the states of the items. /// - /// Each Item element have a state associated to it. It may be "in heap", - /// "pre heap" or "post heap". The latter two are indifferent from the + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the /// heap's point of view, but may be useful to the user. /// /// The item-int map must be initialized in such way that it assigns @@ -84,42 +80,43 @@ ItemIntMap &_iim; public: - /// \brief The constructor. + + /// \brief Constructor. /// - /// The constructor. - /// \param map should be given to the constructor, since it is used - /// internally to handle the cross references. The value of the map - /// must be \c PRE_HEAP (-1) for every item. + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. explicit BinHeap(ItemIntMap &map) : _iim(map) {} - /// \brief The constructor. + /// \brief Constructor. /// - /// The constructor. - /// \param map should be given to the constructor, since it is used - /// internally to handle the cross references. The value of the map - /// should be PRE_HEAP (-1) for each element. - /// - /// \param comp The comparator function object. + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + /// \param comp The function object used for comparing the priorities. BinHeap(ItemIntMap &map, const Compare &comp) : _iim(map), _comp(comp) {} - /// The number of items stored in the heap. + /// \brief The number of items stored in the heap. /// - /// \brief Returns the number of items stored in the heap. + /// This function returns the number of items stored in the heap. int size() const { return _data.size(); } - /// \brief Checks if the heap stores no items. + /// \brief Check if the heap is empty. /// - /// Returns \c true if and only if the heap stores no items. + /// This function returns \c true if the heap is empty. bool empty() const { return _data.empty(); } - /// \brief Make empty this heap. + /// \brief Make the heap empty. /// - /// Make empty this heap. It does not change the cross reference map. - /// If you want to reuse what is not surely empty you should first clear - /// the heap and after that you should set the cross reference map for - /// each item to \c PRE_HEAP. + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. void clear() { _data.clear(); } @@ -127,12 +124,12 @@ private: static int parent(int i) { return (i-1)/2; } - static int second_child(int i) { return 2*i+2; } + static int secondChild(int i) { return 2*i+2; } bool less(const Pair &p1, const Pair &p2) const { return _comp(p1.second, p2.second); } - int bubble_up(int hole, Pair p) { + int bubbleUp(int hole, Pair p) { int par = parent(hole); while( hole>0 && less(p,_data[par]) ) { move(_data[par],hole); @@ -143,8 +140,8 @@ return hole; } - int bubble_down(int hole, Pair p, int length) { - int child = second_child(hole); + int bubbleDown(int hole, Pair p, int length) { + int child = secondChild(hole); while(child < length) { if( less(_data[child-1], _data[child]) ) { --child; @@ -153,7 +150,7 @@ goto ok; move(_data[child], hole); hole = child; - child = second_child(hole); + child = secondChild(hole); } child--; if( child 0) { - bubble_down(0, _data[n], n); + bubbleDown(0, _data[n], n); } _data.pop_back(); } - /// \brief Deletes \c i from the heap. + /// \brief Remove the given item from the heap. /// - /// This method deletes item \c i from the heap. - /// \param i The item to erase. - /// \pre The item should be in the heap. + /// This function removes the given item from the heap if it is + /// already stored. + /// \param i The item to delete. + /// \pre \e i must be in the heap. void erase(const Item &i) { int h = _iim[i]; int n = _data.size()-1; _iim.set(_data[h].first, POST_HEAP); if( h < n ) { - if ( bubble_up(h, _data[n]) == h) { - bubble_down(h, _data[n], n); + if ( bubbleUp(h, _data[n]) == h) { + bubbleDown(h, _data[n], n); } } _data.pop_back(); } - - /// \brief Returns the priority of \c i. + /// \brief The priority of the given item. /// - /// This function returns the priority of item \c i. + /// This function returns the priority of the given item. /// \param i The item. - /// \pre \c i must be in the heap. + /// \pre \e i must be in the heap. Prio operator[](const Item &i) const { int idx = _iim[i]; return _data[idx].second; } - /// \brief \c i gets to the heap with priority \c p independently - /// if \c i was already there. + /// \brief Set the priority of an item or insert it, if it is + /// not stored in the heap. /// - /// This method calls \ref push(\c i, \c p) if \c i is not stored - /// in the heap and sets the priority of \c i to \c p otherwise. + /// This method sets the priority of the given item if it is + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. /// \param i The item. /// \param p The priority. void set(const Item &i, const Prio &p) { @@ -260,44 +261,42 @@ push(i,p); } else if( _comp(p, _data[idx].second) ) { - bubble_up(idx, Pair(i,p)); + bubbleUp(idx, Pair(i,p)); } else { - bubble_down(idx, Pair(i,p), _data.size()); + bubbleDown(idx, Pair(i,p), _data.size()); } } - /// \brief Decreases the priority of \c i to \c p. + /// \brief Decrease the priority of an item to the given value. /// - /// This method decreases the priority of item \c i to \c p. + /// This function decreases the priority of an item to the given value. /// \param i The item. /// \param p The priority. - /// \pre \c i must be stored in the heap with priority at least \c - /// p relative to \c Compare. + /// \pre \e i must be stored in the heap with priority at least \e p. void decrease(const Item &i, const Prio &p) { int idx = _iim[i]; - bubble_up(idx, Pair(i,p)); + bubbleUp(idx, Pair(i,p)); } - /// \brief Increases the priority of \c i to \c p. + /// \brief Increase the priority of an item to the given value. /// - /// This method sets the priority of item \c i to \c p. + /// This function increases the priority of an item to the given value. /// \param i The item. /// \param p The priority. - /// \pre \c i must be stored in the heap with priority at most \c - /// p relative to \c Compare. + /// \pre \e i must be stored in the heap with priority at most \e p. void increase(const Item &i, const Prio &p) { int idx = _iim[i]; - bubble_down(idx, Pair(i,p), _data.size()); + bubbleDown(idx, Pair(i,p), _data.size()); } - /// \brief Returns if \c item is in, has already been in, or has - /// never been in the heap. + /// \brief Return the state of an item. /// - /// This method returns PRE_HEAP if \c item has never been in the - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP - /// otherwise. In the latter case it is possible that \c item will - /// get back to the heap again. + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. /// \param i The item. State state(const Item &i) const { int s = _iim[i]; @@ -306,11 +305,11 @@ return State(s); } - /// \brief Sets the state of the \c item in the heap. + /// \brief Set the state of an item in the heap. /// - /// Sets the state of the \c item in the heap. It can be used to - /// manually clear the heap when it is important to achive the - /// better time complexity. + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. /// \param i The item. /// \param st The state. It should not be \c IN_HEAP. void state(const Item& i, State st) { @@ -327,12 +326,13 @@ } } - /// \brief Replaces an item in the heap. + /// \brief Replace an item in the heap. /// - /// The \c i item is replaced with \c j item. The \c i item should - /// be in the heap, while the \c j should be out of the heap. The - /// \c i item will out of the heap and \c j will be in the heap - /// with the same prioriority as prevoiusly the \c i item. + /// This function replaces item \c i with item \c j. + /// Item \c i must be in the heap, while \c j must be out of the heap. + /// After calling this method, item \c i will be out of the + /// heap and \c j will be in the heap with the same prioriority + /// as item \c i had before. void replace(const Item& i, const Item& j) { int idx = _iim[i]; _iim.set(i, _iim[j]); diff --git a/lemon/bucket_heap.h b/lemon/bucket_heap.h --- a/lemon/bucket_heap.h +++ b/lemon/bucket_heap.h @@ -19,9 +19,9 @@ #ifndef LEMON_BUCKET_HEAP_H #define LEMON_BUCKET_HEAP_H -///\ingroup auxdat +///\ingroup heaps ///\file -///\brief Bucket Heap implementation. +///\brief Bucket heap implementation. #include #include @@ -53,35 +53,41 @@ } - /// \ingroup auxdat + /// \ingroup heaps /// - /// \brief A Bucket Heap implementation. + /// \brief Bucket heap data structure. /// - /// This class implements the \e bucket \e heap data structure. A \e heap - /// is a data structure for storing items with specified values called \e - /// priorities in such a way that finding the item with minimum priority is - /// efficient. The bucket heap is very simple implementation, it can store - /// only integer priorities and it stores for each priority in the - /// \f$ [0..C) \f$ range a list of items. So it should be used only when - /// the priorities are small. It is not intended to use as dijkstra heap. + /// This class implements the \e bucket \e heap data structure. + /// It practically conforms to the \ref concepts::Heap "heap concept", + /// but it has some limitations. /// - /// \param IM A read and write Item int map, used internally - /// to handle the cross references. - /// \param MIN If the given parameter is false then instead of the - /// minimum value the maximum can be retrivied with the top() and - /// prio() member functions. + /// The bucket heap is a very simple structure. It can store only + /// \c int priorities and it maintains a list of items for each priority + /// in the range [0..C). So it should only be used when the + /// priorities are small. It is not intended to use as a Dijkstra heap. + /// + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap. + /// The default is \e min-heap. If this parameter is set to \c false, + /// then the comparison is reversed, so the top(), prio() and pop() + /// functions deal with the item having maximum priority instead of the + /// minimum. + /// + /// \sa SimpleBucketHeap template class BucketHeap { public: - /// \e - typedef typename IM::Key Item; - /// \e + + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. typedef int Prio; - /// \e - typedef std::pair Pair; - /// \e - typedef IM ItemIntMap; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Type of the item-priority pairs. + typedef std::pair Pair; private: @@ -89,10 +95,10 @@ public: - /// \brief Type to represent the items states. + /// \brief Type to represent the states of the items. /// - /// Each Item element have a state associated to it. It may be "in heap", - /// "pre heap" or "post heap". The latter two are indifferent from the + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the /// heap's point of view, but may be useful to the user. /// /// The item-int map must be initialized in such way that it assigns @@ -104,37 +110,39 @@ }; public: - /// \brief The constructor. + + /// \brief Constructor. /// - /// The constructor. - /// \param map should be given to the constructor, since it is used - /// internally to handle the cross references. The value of the map - /// should be PRE_HEAP (-1) for each element. + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {} - /// The number of items stored in the heap. + /// \brief The number of items stored in the heap. /// - /// \brief Returns the number of items stored in the heap. + /// This function returns the number of items stored in the heap. int size() const { return _data.size(); } - /// \brief Checks if the heap stores no items. + /// \brief Check if the heap is empty. /// - /// Returns \c true if and only if the heap stores no items. + /// This function returns \c true if the heap is empty. bool empty() const { return _data.empty(); } - /// \brief Make empty this heap. + /// \brief Make the heap empty. /// - /// Make empty this heap. It does not change the cross reference - /// map. If you want to reuse a heap what is not surely empty you - /// should first clear the heap and after that you should set the - /// cross reference map for each item to \c PRE_HEAP. + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. void clear() { _data.clear(); _first.clear(); _minimum = 0; } private: - void relocate_last(int idx) { + void relocateLast(int idx) { if (idx + 1 < int(_data.size())) { _data[idx] = _data.back(); if (_data[idx].prev != -1) { @@ -174,19 +182,24 @@ } public: + /// \brief Insert a pair of item and priority into the heap. /// - /// Adds \c p.first to the heap with priority \c p.second. + /// This function inserts \c p.first to the heap with priority + /// \c p.second. /// \param p The pair to insert. + /// \pre \c p.first must not be stored in the heap. void push(const Pair& p) { push(p.first, p.second); } /// \brief Insert an item into the heap with the given priority. /// - /// Adds \c i to the heap with priority \c p. + /// This function inserts the given item into the heap with the + /// given priority. /// \param i The item to insert. /// \param p The priority of the item. + /// \pre \e i must not be stored in the heap. void push(const Item &i, const Prio &p) { int idx = _data.size(); _iim[i] = idx; @@ -197,10 +210,10 @@ } } - /// \brief Returns the item with minimum priority. + /// \brief Return the item having minimum priority. /// - /// This method returns the item with minimum priority. - /// \pre The heap must be nonempty. + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. Item top() const { while (_first[_minimum] == -1) { Direction::increase(_minimum); @@ -208,10 +221,10 @@ return _data[_first[_minimum]].item; } - /// \brief Returns the minimum priority. + /// \brief The minimum priority. /// - /// It returns the minimum priority. - /// \pre The heap must be nonempty. + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. Prio prio() const { while (_first[_minimum] == -1) { Direction::increase(_minimum); @@ -219,9 +232,9 @@ return _minimum; } - /// \brief Deletes the item with minimum priority. + /// \brief Remove the item having minimum priority. /// - /// This method deletes the item with minimum priority from the heap. + /// This function removes the item having minimum priority. /// \pre The heap must be non-empty. void pop() { while (_first[_minimum] == -1) { @@ -230,37 +243,38 @@ int idx = _first[_minimum]; _iim[_data[idx].item] = -2; unlace(idx); - relocate_last(idx); + relocateLast(idx); } - /// \brief Deletes \c i from the heap. + /// \brief Remove the given item from the heap. /// - /// This method deletes item \c i from the heap, if \c i was - /// already stored in the heap. - /// \param i The item to erase. + /// This function removes the given item from the heap if it is + /// already stored. + /// \param i The item to delete. + /// \pre \e i must be in the heap. void erase(const Item &i) { int idx = _iim[i]; _iim[_data[idx].item] = -2; unlace(idx); - relocate_last(idx); + relocateLast(idx); } - - /// \brief Returns the priority of \c i. + /// \brief The priority of the given item. /// - /// This function returns the priority of item \c i. - /// \pre \c i must be in the heap. + /// This function returns the priority of the given item. /// \param i The item. + /// \pre \e i must be in the heap. Prio operator[](const Item &i) const { int idx = _iim[i]; return _data[idx].value; } - /// \brief \c i gets to the heap with priority \c p independently - /// if \c i was already there. + /// \brief Set the priority of an item or insert it, if it is + /// not stored in the heap. /// - /// This method calls \ref push(\c i, \c p) if \c i is not stored - /// in the heap and sets the priority of \c i to \c p otherwise. + /// This method sets the priority of the given item if it is + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. /// \param i The item. /// \param p The priority. void set(const Item &i, const Prio &p) { @@ -274,13 +288,12 @@ } } - /// \brief Decreases the priority of \c i to \c p. + /// \brief Decrease the priority of an item to the given value. /// - /// This method decreases the priority of item \c i to \c p. - /// \pre \c i must be stored in the heap with priority at least \c - /// p relative to \c Compare. + /// This function decreases the priority of an item to the given value. /// \param i The item. /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at least \e p. void decrease(const Item &i, const Prio &p) { int idx = _iim[i]; unlace(idx); @@ -291,13 +304,12 @@ lace(idx); } - /// \brief Increases the priority of \c i to \c p. + /// \brief Increase the priority of an item to the given value. /// - /// This method sets the priority of item \c i to \c p. - /// \pre \c i must be stored in the heap with priority at most \c - /// p relative to \c Compare. + /// This function increases the priority of an item to the given value. /// \param i The item. /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at most \e p. void increase(const Item &i, const Prio &p) { int idx = _iim[i]; unlace(idx); @@ -305,13 +317,13 @@ lace(idx); } - /// \brief Returns if \c item is in, has already been in, or has - /// never been in the heap. + /// \brief Return the state of an item. /// - /// This method returns PRE_HEAP if \c item has never been in the - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP - /// otherwise. In the latter case it is possible that \c item will - /// get back to the heap again. + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. /// \param i The item. State state(const Item &i) const { int idx = _iim[i]; @@ -319,11 +331,11 @@ return State(idx); } - /// \brief Sets the state of the \c item in the heap. + /// \brief Set the state of an item in the heap. /// - /// Sets the state of the \c item in the heap. It can be used to - /// manually clear the heap when it is important to achive the - /// better time complexity. + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. /// \param i The item. /// \param st The state. It should not be \c IN_HEAP. void state(const Item& i, State st) { @@ -359,33 +371,44 @@ }; // class BucketHeap - /// \ingroup auxdat + /// \ingroup heaps /// - /// \brief A Simplified Bucket Heap implementation. + /// \brief Simplified bucket heap data structure. /// /// This class implements a simplified \e bucket \e heap data - /// structure. It does not provide some functionality but it faster - /// and simplier data structure than the BucketHeap. The main - /// difference is that the BucketHeap stores for every key a double - /// linked list while this class stores just simple lists. In the - /// other way it does not support erasing each elements just the - /// minimal and it does not supports key increasing, decreasing. + /// structure. It does not provide some functionality, but it is + /// faster and simpler than BucketHeap. The main difference is + /// that BucketHeap stores a doubly-linked list for each key while + /// this class stores only simply-linked lists. It supports erasing + /// only for the item having minimum priority and it does not support + /// key increasing and decreasing. /// - /// \param IM A read and write Item int map, used internally - /// to handle the cross references. - /// \param MIN If the given parameter is false then instead of the - /// minimum value the maximum can be retrivied with the top() and - /// prio() member functions. + /// Note that this implementation does not conform to the + /// \ref concepts::Heap "heap concept" due to the lack of some + /// functionality. + /// + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap. + /// The default is \e min-heap. If this parameter is set to \c false, + /// then the comparison is reversed, so the top(), prio() and pop() + /// functions deal with the item having maximum priority instead of the + /// minimum. /// /// \sa BucketHeap template class SimpleBucketHeap { public: - typedef typename IM::Key Item; + + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. typedef int Prio; - typedef std::pair Pair; - typedef IM ItemIntMap; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Type of the item-priority pairs. + typedef std::pair Pair; private: @@ -393,10 +416,10 @@ public: - /// \brief Type to represent the items states. + /// \brief Type to represent the states of the items. /// - /// Each Item element have a state associated to it. It may be "in heap", - /// "pre heap" or "post heap". The latter two are indifferent from the + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the /// heap's point of view, but may be useful to the user. /// /// The item-int map must be initialized in such way that it assigns @@ -409,48 +432,53 @@ public: - /// \brief The constructor. + /// \brief Constructor. /// - /// The constructor. - /// \param map should be given to the constructor, since it is used - /// internally to handle the cross references. The value of the map - /// should be PRE_HEAP (-1) for each element. + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. explicit SimpleBucketHeap(ItemIntMap &map) : _iim(map), _free(-1), _num(0), _minimum(0) {} - /// \brief Returns the number of items stored in the heap. + /// \brief The number of items stored in the heap. /// - /// The number of items stored in the heap. + /// This function returns the number of items stored in the heap. int size() const { return _num; } - /// \brief Checks if the heap stores no items. + /// \brief Check if the heap is empty. /// - /// Returns \c true if and only if the heap stores no items. + /// This function returns \c true if the heap is empty. bool empty() const { return _num == 0; } - /// \brief Make empty this heap. + /// \brief Make the heap empty. /// - /// Make empty this heap. It does not change the cross reference - /// map. If you want to reuse a heap what is not surely empty you - /// should first clear the heap and after that you should set the - /// cross reference map for each item to \c PRE_HEAP. + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. void clear() { _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0; } /// \brief Insert a pair of item and priority into the heap. /// - /// Adds \c p.first to the heap with priority \c p.second. + /// This function inserts \c p.first to the heap with priority + /// \c p.second. /// \param p The pair to insert. + /// \pre \c p.first must not be stored in the heap. void push(const Pair& p) { push(p.first, p.second); } /// \brief Insert an item into the heap with the given priority. /// - /// Adds \c i to the heap with priority \c p. + /// This function inserts the given item into the heap with the + /// given priority. /// \param i The item to insert. /// \param p The priority of the item. + /// \pre \e i must not be stored in the heap. void push(const Item &i, const Prio &p) { int idx; if (_free == -1) { @@ -471,10 +499,10 @@ ++_num; } - /// \brief Returns the item with minimum priority. + /// \brief Return the item having minimum priority. /// - /// This method returns the item with minimum priority. - /// \pre The heap must be nonempty. + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. Item top() const { while (_first[_minimum] == -1) { Direction::increase(_minimum); @@ -482,10 +510,10 @@ return _data[_first[_minimum]].item; } - /// \brief Returns the minimum priority. + /// \brief The minimum priority. /// - /// It returns the minimum priority. - /// \pre The heap must be nonempty. + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. Prio prio() const { while (_first[_minimum] == -1) { Direction::increase(_minimum); @@ -493,9 +521,9 @@ return _minimum; } - /// \brief Deletes the item with minimum priority. + /// \brief Remove the item having minimum priority. /// - /// This method deletes the item with minimum priority from the heap. + /// This function removes the item having minimum priority. /// \pre The heap must be non-empty. void pop() { while (_first[_minimum] == -1) { @@ -509,16 +537,15 @@ --_num; } - /// \brief Returns the priority of \c i. + /// \brief The priority of the given item. /// - /// This function returns the priority of item \c i. - /// \warning This operator is not a constant time function - /// because it scans the whole data structure to find the proper - /// value. - /// \pre \c i must be in the heap. + /// This function returns the priority of the given item. /// \param i The item. + /// \pre \e i must be in the heap. + /// \warning This operator is not a constant time function because + /// it scans the whole data structure to find the proper value. Prio operator[](const Item &i) const { - for (int k = 0; k < _first.size(); ++k) { + for (int k = 0; k < int(_first.size()); ++k) { int idx = _first[k]; while (idx != -1) { if (_data[idx].item == i) { @@ -530,13 +557,13 @@ return -1; } - /// \brief Returns if \c item is in, has already been in, or has - /// never been in the heap. + /// \brief Return the state of an item. /// - /// This method returns PRE_HEAP if \c item has never been in the - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP - /// otherwise. In the latter case it is possible that \c item will - /// get back to the heap again. + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. /// \param i The item. State state(const Item &i) const { int idx = _iim[i]; diff --git a/lemon/concepts/heap.h b/lemon/concepts/heap.h --- a/lemon/concepts/heap.h +++ b/lemon/concepts/heap.h @@ -16,13 +16,13 @@ * */ +#ifndef LEMON_CONCEPTS_HEAP_H +#define LEMON_CONCEPTS_HEAP_H + ///\ingroup concept ///\file ///\brief The concept of heaps. -#ifndef LEMON_CONCEPTS_HEAP_H -#define LEMON_CONCEPTS_HEAP_H - #include #include @@ -35,21 +35,27 @@ /// \brief The heap concept. /// - /// Concept class describing the main interface of heaps. A \e heap - /// is a data structure for storing items with specified values called - /// \e priorities in such a way that finding the item with minimum - /// priority is efficient. In a heap one can change the priority of an - /// item, add or erase an item, etc. + /// This concept class describes the main interface of heaps. + /// The various \ref heaps "heap structures" are efficient + /// implementations of the abstract data type \e priority \e queue. + /// They store items with specified values called \e priorities + /// in such a way that finding and removing the item with minimum + /// priority are efficient. The basic operations are adding and + /// erasing items, changing the priority of an item, etc. /// - /// \tparam PR Type of the priority of the items. - /// \tparam IM A read and writable item map with int values, used + /// Heaps are crucial in several algorithms, such as Dijkstra and Prim. + /// Any class that conforms to this concept can be used easily in such + /// algorithms. + /// + /// \tparam PR Type of the priorities of the items. + /// \tparam IM A read-writable item map with \c int values, used /// internally to handle the cross references. - /// \tparam Comp A functor class for the ordering of the priorities. + /// \tparam CMP A functor class for comparing the priorities. /// The default is \c std::less. #ifdef DOXYGEN - template > + template #else - template + template > #endif class Heap { public: @@ -64,109 +70,125 @@ /// \brief Type to represent the states of the items. /// /// Each item has a state associated to it. It can be "in heap", - /// "pre heap" or "post heap". The later two are indifferent - /// from the point of view of the heap, but may be useful for - /// the user. + /// "pre-heap" or "post-heap". The latter two are indifferent from the + /// heap's point of view, but may be useful to the user. /// /// The item-int map must be initialized in such way that it assigns /// \c PRE_HEAP (-1) to any element to be put in the heap. enum State { IN_HEAP = 0, ///< = 0. The "in heap" state constant. - PRE_HEAP = -1, ///< = -1. The "pre heap" state constant. - POST_HEAP = -2 ///< = -2. The "post heap" state constant. + PRE_HEAP = -1, ///< = -1. The "pre-heap" state constant. + POST_HEAP = -2 ///< = -2. The "post-heap" state constant. }; - /// \brief The constructor. + /// \brief Constructor. /// - /// The constructor. + /// Constructor. /// \param map A map that assigns \c int values to keys of type /// \c Item. It is used internally by the heap implementations to /// handle the cross references. The assigned value must be - /// \c PRE_HEAP (-1) for every item. + /// \c PRE_HEAP (-1) for each item. explicit Heap(ItemIntMap &map) {} + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to keys of type + /// \c Item. It is used internally by the heap implementations to + /// handle the cross references. The assigned value must be + /// \c PRE_HEAP (-1) for each item. + /// \param comp The function object used for comparing the priorities. + explicit Heap(ItemIntMap &map, const CMP &comp) {} + /// \brief The number of items stored in the heap. /// - /// Returns the number of items stored in the heap. + /// This function returns the number of items stored in the heap. int size() const { return 0; } - /// \brief Checks if the heap is empty. + /// \brief Check if the heap is empty. /// - /// Returns \c true if the heap is empty. + /// This function returns \c true if the heap is empty. bool empty() const { return false; } - /// \brief Makes the heap empty. + /// \brief Make the heap empty. /// - /// Makes the heap empty. - void clear(); + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + void clear() {} - /// \brief Inserts an item into the heap with the given priority. + /// \brief Insert an item into the heap with the given priority. /// - /// Inserts the given item into the heap with the given priority. + /// This function inserts the given item into the heap with the + /// given priority. /// \param i The item to insert. /// \param p The priority of the item. + /// \pre \e i must not be stored in the heap. void push(const Item &i, const Prio &p) {} - /// \brief Returns the item having minimum priority. + /// \brief Return the item having minimum priority. /// - /// Returns the item having minimum priority. + /// This function returns the item having minimum priority. /// \pre The heap must be non-empty. Item top() const {} /// \brief The minimum priority. /// - /// Returns the minimum priority. + /// This function returns the minimum priority. /// \pre The heap must be non-empty. Prio prio() const {} - /// \brief Removes the item having minimum priority. + /// \brief Remove the item having minimum priority. /// - /// Removes the item having minimum priority. + /// This function removes the item having minimum priority. /// \pre The heap must be non-empty. void pop() {} - /// \brief Removes an item from the heap. + /// \brief Remove the given item from the heap. /// - /// Removes the given item from the heap if it is already stored. + /// This function removes the given item from the heap if it is + /// already stored. /// \param i The item to delete. + /// \pre \e i must be in the heap. void erase(const Item &i) {} - /// \brief The priority of an item. + /// \brief The priority of the given item. /// - /// Returns the priority of the given item. + /// This function returns the priority of the given item. /// \param i The item. - /// \pre \c i must be in the heap. + /// \pre \e i must be in the heap. Prio operator[](const Item &i) const {} - /// \brief Sets the priority of an item or inserts it, if it is + /// \brief Set the priority of an item or insert it, if it is /// not stored in the heap. /// /// This method sets the priority of the given item if it is - /// already stored in the heap. - /// Otherwise it inserts the given item with the given priority. + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. /// /// \param i The item. /// \param p The priority. void set(const Item &i, const Prio &p) {} - /// \brief Decreases the priority of an item to the given value. + /// \brief Decrease the priority of an item to the given value. /// - /// Decreases the priority of an item to the given value. + /// This function decreases the priority of an item to the given value. /// \param i The item. /// \param p The priority. - /// \pre \c i must be stored in the heap with priority at least \c p. + /// \pre \e i must be stored in the heap with priority at least \e p. void decrease(const Item &i, const Prio &p) {} - /// \brief Increases the priority of an item to the given value. + /// \brief Increase the priority of an item to the given value. /// - /// Increases the priority of an item to the given value. + /// This function increases the priority of an item to the given value. /// \param i The item. /// \param p The priority. - /// \pre \c i must be stored in the heap with priority at most \c p. + /// \pre \e i must be stored in the heap with priority at most \e p. void increase(const Item &i, const Prio &p) {} - /// \brief Returns if an item is in, has already been in, or has - /// never been in the heap. + /// \brief Return the state of an item. /// /// This method returns \c PRE_HEAP if the given item has never /// been in the heap, \c IN_HEAP if it is in the heap at the moment, @@ -176,11 +198,11 @@ /// \param i The item. State state(const Item &i) const {} - /// \brief Sets the state of an item in the heap. + /// \brief Set the state of an item in the heap. /// - /// Sets the state of the given item in the heap. It can be used - /// to manually clear the heap when it is important to achive the - /// better time complexity. + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. /// \param i The item. /// \param st The state. It should not be \c IN_HEAP. void state(const Item& i, State st) {} diff --git a/lemon/fib_heap.h b/lemon/fib_heap.h --- a/lemon/fib_heap.h +++ b/lemon/fib_heap.h @@ -20,53 +20,49 @@ #define LEMON_FIB_HEAP_H ///\file -///\ingroup auxdat -///\brief Fibonacci Heap implementation. +///\ingroup heaps +///\brief Fibonacci heap implementation. #include +#include #include #include namespace lemon { - /// \ingroup auxdat + /// \ingroup heaps /// - ///\brief Fibonacci Heap. + /// \brief Fibonacci heap data structure. /// - ///This class implements the \e Fibonacci \e heap data structure. A \e heap - ///is a data structure for storing items with specified values called \e - ///priorities in such a way that finding the item with minimum priority is - ///efficient. \c CMP specifies the ordering of the priorities. In a heap - ///one can change the priority of an item, add or erase an item, etc. + /// This class implements the \e Fibonacci \e heap data structure. + /// It fully conforms to the \ref concepts::Heap "heap concept". /// - ///The methods \ref increase and \ref erase are not efficient in a Fibonacci - ///heap. In case of many calls to these operations, it is better to use a - ///\ref BinHeap "binary heap". + /// The methods \ref increase() and \ref erase() are not efficient in a + /// Fibonacci heap. In case of many calls of these operations, it is + /// better to use other heap structure, e.g. \ref BinHeap "binary heap". /// - ///\param PRIO Type of the priority of the items. - ///\param IM A read and writable Item int map, used internally - ///to handle the cross references. - ///\param CMP A class for the ordering of the priorities. The - ///default is \c std::less. - /// - ///\sa BinHeap - ///\sa Dijkstra + /// \tparam PR Type of the priorities of the items. + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam CMP A functor class for comparing the priorities. + /// The default is \c std::less. #ifdef DOXYGEN - template + template #else - template > + template > #endif class FibHeap { public: - ///\e + + /// Type of the item-int map. typedef IM ItemIntMap; - ///\e - typedef PRIO Prio; - ///\e + /// Type of the priorities. + typedef PR Prio; + /// Type of the items stored in the heap. typedef typename ItemIntMap::Key Item; - ///\e + /// Type of the item-priority pairs. typedef std::pair Pair; - ///\e + /// Functor type for comparing the priorities. typedef CMP Compare; private: @@ -80,10 +76,10 @@ public: - /// \brief Type to represent the items states. + /// \brief Type to represent the states of the items. /// - /// Each Item element have a state associated to it. It may be "in heap", - /// "pre heap" or "post heap". The latter two are indifferent from the + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the /// heap's point of view, but may be useful to the user. /// /// The item-int map must be initialized in such way that it assigns @@ -94,60 +90,54 @@ POST_HEAP = -2 ///< = -2. }; - /// \brief The constructor + /// \brief Constructor. /// - /// \c map should be given to the constructor, since it is - /// used internally to handle the cross references. + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. explicit FibHeap(ItemIntMap &map) : _minimum(0), _iim(map), _num() {} - /// \brief The constructor + /// \brief Constructor. /// - /// \c map should be given to the constructor, since it is used - /// internally to handle the cross references. \c comp is an - /// object for ordering of the priorities. + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + /// \param comp The function object used for comparing the priorities. FibHeap(ItemIntMap &map, const Compare &comp) : _minimum(0), _iim(map), _comp(comp), _num() {} /// \brief The number of items stored in the heap. /// - /// Returns the number of items stored in the heap. + /// This function returns the number of items stored in the heap. int size() const { return _num; } - /// \brief Checks if the heap stores no items. + /// \brief Check if the heap is empty. /// - /// Returns \c true if and only if the heap stores no items. + /// This function returns \c true if the heap is empty. bool empty() const { return _num==0; } - /// \brief Make empty this heap. + /// \brief Make the heap empty. /// - /// Make empty this heap. It does not change the cross reference - /// map. If you want to reuse a heap what is not surely empty you - /// should first clear the heap and after that you should set the - /// cross reference map for each item to \c PRE_HEAP. + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. void clear() { _data.clear(); _minimum = 0; _num = 0; } - /// \brief \c item gets to the heap with priority \c value independently - /// if \c item was already there. + /// \brief Insert an item into the heap with the given priority. /// - /// This method calls \ref push(\c item, \c value) if \c item is not - /// stored in the heap and it calls \ref decrease(\c item, \c value) or - /// \ref increase(\c item, \c value) otherwise. - void set (const Item& item, const Prio& value) { - int i=_iim[item]; - if ( i >= 0 && _data[i].in ) { - if ( _comp(value, _data[i].prio) ) decrease(item, value); - if ( _comp(_data[i].prio, value) ) increase(item, value); - } else push(item, value); - } - - /// \brief Adds \c item to the heap with priority \c value. - /// - /// Adds \c item to the heap with priority \c value. - /// \pre \c item must not be stored in the heap. - void push (const Item& item, const Prio& value) { + /// This function inserts the given item into the heap with the + /// given priority. + /// \param item The item to insert. + /// \param prio The priority of the item. + /// \pre \e item must not be stored in the heap. + void push (const Item& item, const Prio& prio) { int i=_iim[item]; if ( i < 0 ) { int s=_data.size(); @@ -168,47 +158,37 @@ _data[i].right_neighbor=_data[_minimum].right_neighbor; _data[_minimum].right_neighbor=i; _data[i].left_neighbor=_minimum; - if ( _comp( value, _data[_minimum].prio) ) _minimum=i; + if ( _comp( prio, _data[_minimum].prio) ) _minimum=i; } else { _data[i].right_neighbor=_data[i].left_neighbor=i; _minimum=i; } - _data[i].prio=value; + _data[i].prio=prio; ++_num; } - /// \brief Returns the item with minimum priority relative to \c Compare. + /// \brief Return the item having minimum priority. /// - /// This method returns the item with minimum priority relative to \c - /// Compare. - /// \pre The heap must be nonempty. + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. Item top() const { return _data[_minimum].name; } - /// \brief Returns the minimum priority relative to \c Compare. + /// \brief The minimum priority. /// - /// It returns the minimum priority relative to \c Compare. - /// \pre The heap must be nonempty. - const Prio& prio() const { return _data[_minimum].prio; } + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. + Prio prio() const { return _data[_minimum].prio; } - /// \brief Returns the priority of \c item. + /// \brief Remove the item having minimum priority. /// - /// It returns the priority of \c item. - /// \pre \c item must be in the heap. - const Prio& operator[](const Item& item) const { - return _data[_iim[item]].prio; - } - - /// \brief Deletes the item with minimum priority relative to \c Compare. - /// - /// This method deletes the item with minimum priority relative to \c - /// Compare from the heap. + /// This function removes the item having minimum priority. /// \pre The heap must be non-empty. void pop() { /*The first case is that there are only one root.*/ if ( _data[_minimum].left_neighbor==_minimum ) { _data[_minimum].in=false; if ( _data[_minimum].degree!=0 ) { - makeroot(_data[_minimum].child); + makeRoot(_data[_minimum].child); _minimum=_data[_minimum].child; balance(); } @@ -221,7 +201,7 @@ int child=_data[_minimum].child; int last_child=_data[child].left_neighbor; - makeroot(child); + makeRoot(child); _data[left].right_neighbor=child; _data[child].left_neighbor=left; @@ -234,10 +214,12 @@ --_num; } - /// \brief Deletes \c item from the heap. + /// \brief Remove the given item from the heap. /// - /// This method deletes \c item from the heap, if \c item was already - /// stored in the heap. It is quite inefficient in Fibonacci heaps. + /// This function removes the given item from the heap if it is + /// already stored. + /// \param item The item to delete. + /// \pre \e item must be in the heap. void erase (const Item& item) { int i=_iim[item]; @@ -252,43 +234,68 @@ } } - /// \brief Decreases the priority of \c item to \c value. + /// \brief The priority of the given item. /// - /// This method decreases the priority of \c item to \c value. - /// \pre \c item must be stored in the heap with priority at least \c - /// value relative to \c Compare. - void decrease (Item item, const Prio& value) { + /// This function returns the priority of the given item. + /// \param item The item. + /// \pre \e item must be in the heap. + Prio operator[](const Item& item) const { + return _data[_iim[item]].prio; + } + + /// \brief Set the priority of an item or insert it, if it is + /// not stored in the heap. + /// + /// This method sets the priority of the given item if it is + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. + /// \param item The item. + /// \param prio The priority. + void set (const Item& item, const Prio& prio) { int i=_iim[item]; - _data[i].prio=value; + if ( i >= 0 && _data[i].in ) { + if ( _comp(prio, _data[i].prio) ) decrease(item, prio); + if ( _comp(_data[i].prio, prio) ) increase(item, prio); + } else push(item, prio); + } + + /// \brief Decrease the priority of an item to the given value. + /// + /// This function decreases the priority of an item to the given value. + /// \param item The item. + /// \param prio The priority. + /// \pre \e item must be stored in the heap with priority at least \e prio. + void decrease (const Item& item, const Prio& prio) { + int i=_iim[item]; + _data[i].prio=prio; int p=_data[i].parent; - if ( p!=-1 && _comp(value, _data[p].prio) ) { + if ( p!=-1 && _comp(prio, _data[p].prio) ) { cut(i,p); cascade(p); } - if ( _comp(value, _data[_minimum].prio) ) _minimum=i; + if ( _comp(prio, _data[_minimum].prio) ) _minimum=i; } - /// \brief Increases the priority of \c item to \c value. + /// \brief Increase the priority of an item to the given value. /// - /// This method sets the priority of \c item to \c value. Though - /// there is no precondition on the priority of \c item, this - /// method should be used only if it is indeed necessary to increase - /// (relative to \c Compare) the priority of \c item, because this - /// method is inefficient. - void increase (Item item, const Prio& value) { + /// This function increases the priority of an item to the given value. + /// \param item The item. + /// \param prio The priority. + /// \pre \e item must be stored in the heap with priority at most \e prio. + void increase (const Item& item, const Prio& prio) { erase(item); - push(item, value); + push(item, prio); } - - /// \brief Returns if \c item is in, has already been in, or has never - /// been in the heap. + /// \brief Return the state of an item. /// - /// This method returns PRE_HEAP if \c item has never been in the - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP - /// otherwise. In the latter case it is possible that \c item will - /// get back to the heap again. + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. + /// \param item The item. State state(const Item &item) const { int i=_iim[item]; if( i>=0 ) { @@ -298,11 +305,11 @@ return State(i); } - /// \brief Sets the state of the \c item in the heap. + /// \brief Set the state of an item in the heap. /// - /// Sets the state of the \c item in the heap. It can be used to - /// manually clear the heap when it is important to achive the - /// better time _complexity. + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. /// \param i The item. /// \param st The state. It should not be \c IN_HEAP. void state(const Item& i, State st) { @@ -365,7 +372,7 @@ } while ( s != m ); } - void makeroot(int c) { + void makeRoot(int c) { int s=c; do { _data[s].parent=-1; diff --git a/lemon/radix_heap.h b/lemon/radix_heap.h --- a/lemon/radix_heap.h +++ b/lemon/radix_heap.h @@ -19,9 +19,9 @@ #ifndef LEMON_RADIX_HEAP_H #define LEMON_RADIX_HEAP_H -///\ingroup auxdat +///\ingroup heaps ///\file -///\brief Radix Heap implementation. +///\brief Radix heap implementation. #include #include @@ -29,56 +29,54 @@ namespace lemon { - /// \ingroup auxdata + /// \ingroup heaps /// - /// \brief A Radix Heap implementation. + /// \brief Radix heap data structure. /// - /// This class implements the \e radix \e heap data structure. A \e heap - /// is a data structure for storing items with specified values called \e - /// priorities in such a way that finding the item with minimum priority is - /// efficient. This heap type can store only items with \e int priority. - /// In a heap one can change the priority of an item, add or erase an - /// item, but the priority cannot be decreased under the last removed - /// item's priority. + /// This class implements the \e radix \e heap data structure. + /// It practically conforms to the \ref concepts::Heap "heap concept", + /// but it has some limitations due its special implementation. + /// The type of the priorities must be \c int and the priority of an + /// item cannot be decreased under the priority of the last removed item. /// - /// \param IM A read and writable Item int map, used internally - /// to handle the cross references. - /// - /// \see BinHeap - /// \see Dijkstra + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. template class RadixHeap { public: - typedef typename IM::Key Item; + + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. typedef int Prio; - typedef IM ItemIntMap; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; /// \brief Exception thrown by RadixHeap. /// - /// This Exception is thrown when a smaller priority - /// is inserted into the \e RadixHeap then the last time erased. + /// This exception is thrown when an item is inserted into a + /// RadixHeap with a priority smaller than the last erased one. /// \see RadixHeap - - class UnderFlowPriorityError : public Exception { + class PriorityUnderflowError : public Exception { public: virtual const char* what() const throw() { - return "lemon::RadixHeap::UnderFlowPriorityError"; + return "lemon::RadixHeap::PriorityUnderflowError"; } }; - /// \brief Type to represent the items states. + /// \brief Type to represent the states of the items. /// - /// Each Item element have a state associated to it. It may be "in heap", - /// "pre heap" or "post heap". The latter two are indifferent from the + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the /// heap's point of view, but may be useful to the user. /// - /// The ItemIntMap \e should be initialized in such way that it maps - /// PRE_HEAP (-1) to any element to be put in the heap... + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. enum State { - IN_HEAP = 0, - PRE_HEAP = -1, - POST_HEAP = -2 + IN_HEAP = 0, ///< = 0. + PRE_HEAP = -1, ///< = -1. + POST_HEAP = -2 ///< = -2. }; private: @@ -96,52 +94,55 @@ RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {} }; - std::vector data; - std::vector boxes; + std::vector _data; + std::vector _boxes; ItemIntMap &_iim; + public: - public: - /// \brief The constructor. + /// \brief Constructor. /// - /// The constructor. - /// - /// \param map It should be given to the constructor, since it is used - /// internally to handle the cross references. The value of the map - /// should be PRE_HEAP (-1) for each element. - /// - /// \param minimal The initial minimal value of the heap. - /// \param capacity It determines the initial capacity of the heap. - RadixHeap(ItemIntMap &map, int minimal = 0, int capacity = 0) - : _iim(map) { - boxes.push_back(RadixBox(minimal, 1)); - boxes.push_back(RadixBox(minimal + 1, 1)); - while (lower(boxes.size() - 1, capacity + minimal - 1)) { + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + /// \param minimum The initial minimum value of the heap. + /// \param capacity The initial capacity of the heap. + RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0) + : _iim(map) + { + _boxes.push_back(RadixBox(minimum, 1)); + _boxes.push_back(RadixBox(minimum + 1, 1)); + while (lower(_boxes.size() - 1, capacity + minimum - 1)) { extend(); } } - /// The number of items stored in the heap. + /// \brief The number of items stored in the heap. /// - /// \brief Returns the number of items stored in the heap. - int size() const { return data.size(); } - /// \brief Checks if the heap stores no items. + /// This function returns the number of items stored in the heap. + int size() const { return _data.size(); } + + /// \brief Check if the heap is empty. /// - /// Returns \c true if and only if the heap stores no items. - bool empty() const { return data.empty(); } + /// This function returns \c true if the heap is empty. + bool empty() const { return _data.empty(); } - /// \brief Make empty this heap. + /// \brief Make the heap empty. /// - /// Make empty this heap. It does not change the cross reference - /// map. If you want to reuse a heap what is not surely empty you - /// should first clear the heap and after that you should set the - /// cross reference map for each item to \c PRE_HEAP. - void clear(int minimal = 0, int capacity = 0) { - data.clear(); boxes.clear(); - boxes.push_back(RadixBox(minimal, 1)); - boxes.push_back(RadixBox(minimal + 1, 1)); - while (lower(boxes.size() - 1, capacity + minimal - 1)) { + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + /// \param minimum The minimum value of the heap. + /// \param capacity The capacity of the heap. + void clear(int minimum = 0, int capacity = 0) { + _data.clear(); _boxes.clear(); + _boxes.push_back(RadixBox(minimum, 1)); + _boxes.push_back(RadixBox(minimum + 1, 1)); + while (lower(_boxes.size() - 1, capacity + minimum - 1)) { extend(); } } @@ -149,255 +150,259 @@ private: bool upper(int box, Prio pr) { - return pr < boxes[box].min; + return pr < _boxes[box].min; } bool lower(int box, Prio pr) { - return pr >= boxes[box].min + boxes[box].size; + return pr >= _boxes[box].min + _boxes[box].size; } - /// \brief Remove item from the box list. + // Remove item from the box list void remove(int index) { - if (data[index].prev >= 0) { - data[data[index].prev].next = data[index].next; + if (_data[index].prev >= 0) { + _data[_data[index].prev].next = _data[index].next; } else { - boxes[data[index].box].first = data[index].next; + _boxes[_data[index].box].first = _data[index].next; } - if (data[index].next >= 0) { - data[data[index].next].prev = data[index].prev; + if (_data[index].next >= 0) { + _data[_data[index].next].prev = _data[index].prev; } } - /// \brief Insert item into the box list. + // Insert item into the box list void insert(int box, int index) { - if (boxes[box].first == -1) { - boxes[box].first = index; - data[index].next = data[index].prev = -1; + if (_boxes[box].first == -1) { + _boxes[box].first = index; + _data[index].next = _data[index].prev = -1; } else { - data[index].next = boxes[box].first; - data[boxes[box].first].prev = index; - data[index].prev = -1; - boxes[box].first = index; + _data[index].next = _boxes[box].first; + _data[_boxes[box].first].prev = index; + _data[index].prev = -1; + _boxes[box].first = index; } - data[index].box = box; + _data[index].box = box; } - /// \brief Add a new box to the box list. + // Add a new box to the box list void extend() { - int min = boxes.back().min + boxes.back().size; - int bs = 2 * boxes.back().size; - boxes.push_back(RadixBox(min, bs)); + int min = _boxes.back().min + _boxes.back().size; + int bs = 2 * _boxes.back().size; + _boxes.push_back(RadixBox(min, bs)); } - /// \brief Move an item up into the proper box. - void bubble_up(int index) { - if (!lower(data[index].box, data[index].prio)) return; + // Move an item up into the proper box. + void bubbleUp(int index) { + if (!lower(_data[index].box, _data[index].prio)) return; remove(index); - int box = findUp(data[index].box, data[index].prio); + int box = findUp(_data[index].box, _data[index].prio); insert(box, index); } - /// \brief Find up the proper box for the item with the given prio. + // Find up the proper box for the item with the given priority int findUp(int start, int pr) { while (lower(start, pr)) { - if (++start == int(boxes.size())) { + if (++start == int(_boxes.size())) { extend(); } } return start; } - /// \brief Move an item down into the proper box. - void bubble_down(int index) { - if (!upper(data[index].box, data[index].prio)) return; + // Move an item down into the proper box + void bubbleDown(int index) { + if (!upper(_data[index].box, _data[index].prio)) return; remove(index); - int box = findDown(data[index].box, data[index].prio); + int box = findDown(_data[index].box, _data[index].prio); insert(box, index); } - /// \brief Find up the proper box for the item with the given prio. + // Find down the proper box for the item with the given priority int findDown(int start, int pr) { while (upper(start, pr)) { - if (--start < 0) throw UnderFlowPriorityError(); + if (--start < 0) throw PriorityUnderflowError(); } return start; } - /// \brief Find the first not empty box. + // Find the first non-empty box int findFirst() { int first = 0; - while (boxes[first].first == -1) ++first; + while (_boxes[first].first == -1) ++first; return first; } - /// \brief Gives back the minimal prio of the box. + // Gives back the minimum priority of the given box int minValue(int box) { - int min = data[boxes[box].first].prio; - for (int k = boxes[box].first; k != -1; k = data[k].next) { - if (data[k].prio < min) min = data[k].prio; + int min = _data[_boxes[box].first].prio; + for (int k = _boxes[box].first; k != -1; k = _data[k].next) { + if (_data[k].prio < min) min = _data[k].prio; } return min; } - /// \brief Rearrange the items of the heap and makes the - /// first box not empty. + // Rearrange the items of the heap and make the first box non-empty void moveDown() { int box = findFirst(); if (box == 0) return; int min = minValue(box); for (int i = 0; i <= box; ++i) { - boxes[i].min = min; - min += boxes[i].size; + _boxes[i].min = min; + min += _boxes[i].size; } - int curr = boxes[box].first, next; + int curr = _boxes[box].first, next; while (curr != -1) { - next = data[curr].next; - bubble_down(curr); + next = _data[curr].next; + bubbleDown(curr); curr = next; } } - void relocate_last(int index) { - if (index != int(data.size()) - 1) { - data[index] = data.back(); - if (data[index].prev != -1) { - data[data[index].prev].next = index; + void relocateLast(int index) { + if (index != int(_data.size()) - 1) { + _data[index] = _data.back(); + if (_data[index].prev != -1) { + _data[_data[index].prev].next = index; } else { - boxes[data[index].box].first = index; + _boxes[_data[index].box].first = index; } - if (data[index].next != -1) { - data[data[index].next].prev = index; + if (_data[index].next != -1) { + _data[_data[index].next].prev = index; } - _iim[data[index].item] = index; + _iim[_data[index].item] = index; } - data.pop_back(); + _data.pop_back(); } public: /// \brief Insert an item into the heap with the given priority. /// - /// Adds \c i to the heap with priority \c p. + /// This function inserts the given item into the heap with the + /// given priority. /// \param i The item to insert. /// \param p The priority of the item. + /// \pre \e i must not be stored in the heap. + /// \warning This method may throw an \c UnderFlowPriorityException. void push(const Item &i, const Prio &p) { - int n = data.size(); + int n = _data.size(); _iim.set(i, n); - data.push_back(RadixItem(i, p)); - while (lower(boxes.size() - 1, p)) { + _data.push_back(RadixItem(i, p)); + while (lower(_boxes.size() - 1, p)) { extend(); } - int box = findDown(boxes.size() - 1, p); + int box = findDown(_boxes.size() - 1, p); insert(box, n); } - /// \brief Returns the item with minimum priority. + /// \brief Return the item having minimum priority. /// - /// This method returns the item with minimum priority. - /// \pre The heap must be nonempty. + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. Item top() const { const_cast&>(*this).moveDown(); - return data[boxes[0].first].item; + return _data[_boxes[0].first].item; } - /// \brief Returns the minimum priority. + /// \brief The minimum priority. /// - /// It returns the minimum priority. - /// \pre The heap must be nonempty. + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. Prio prio() const { const_cast&>(*this).moveDown(); - return data[boxes[0].first].prio; + return _data[_boxes[0].first].prio; } - /// \brief Deletes the item with minimum priority. + /// \brief Remove the item having minimum priority. /// - /// This method deletes the item with minimum priority. + /// This function removes the item having minimum priority. /// \pre The heap must be non-empty. void pop() { moveDown(); - int index = boxes[0].first; - _iim[data[index].item] = POST_HEAP; + int index = _boxes[0].first; + _iim[_data[index].item] = POST_HEAP; remove(index); - relocate_last(index); + relocateLast(index); } - /// \brief Deletes \c i from the heap. + /// \brief Remove the given item from the heap. /// - /// This method deletes item \c i from the heap, if \c i was - /// already stored in the heap. - /// \param i The item to erase. + /// This function removes the given item from the heap if it is + /// already stored. + /// \param i The item to delete. + /// \pre \e i must be in the heap. void erase(const Item &i) { int index = _iim[i]; _iim[i] = POST_HEAP; remove(index); - relocate_last(index); + relocateLast(index); } - /// \brief Returns the priority of \c i. + /// \brief The priority of the given item. /// - /// This function returns the priority of item \c i. - /// \pre \c i must be in the heap. + /// This function returns the priority of the given item. /// \param i The item. + /// \pre \e i must be in the heap. Prio operator[](const Item &i) const { int idx = _iim[i]; - return data[idx].prio; + return _data[idx].prio; } - /// \brief \c i gets to the heap with priority \c p independently - /// if \c i was already there. + /// \brief Set the priority of an item or insert it, if it is + /// not stored in the heap. /// - /// This method calls \ref push(\c i, \c p) if \c i is not stored - /// in the heap and sets the priority of \c i to \c p otherwise. - /// It may throw an \e UnderFlowPriorityException. + /// This method sets the priority of the given item if it is + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. /// \param i The item. /// \param p The priority. + /// \pre \e i must be in the heap. + /// \warning This method may throw an \c UnderFlowPriorityException. void set(const Item &i, const Prio &p) { int idx = _iim[i]; if( idx < 0 ) { push(i, p); } - else if( p >= data[idx].prio ) { - data[idx].prio = p; - bubble_up(idx); + else if( p >= _data[idx].prio ) { + _data[idx].prio = p; + bubbleUp(idx); } else { - data[idx].prio = p; - bubble_down(idx); + _data[idx].prio = p; + bubbleDown(idx); } } - - /// \brief Decreases the priority of \c i to \c p. + /// \brief Decrease the priority of an item to the given value. /// - /// This method decreases the priority of item \c i to \c p. - /// \pre \c i must be stored in the heap with priority at least \c p, and - /// \c should be greater or equal to the last removed item's priority. + /// This function decreases the priority of an item to the given value. /// \param i The item. /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at least \e p. + /// \warning This method may throw an \c UnderFlowPriorityException. void decrease(const Item &i, const Prio &p) { int idx = _iim[i]; - data[idx].prio = p; - bubble_down(idx); + _data[idx].prio = p; + bubbleDown(idx); } - /// \brief Increases the priority of \c i to \c p. + /// \brief Increase the priority of an item to the given value. /// - /// This method sets the priority of item \c i to \c p. - /// \pre \c i must be stored in the heap with priority at most \c p + /// This function increases the priority of an item to the given value. /// \param i The item. /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at most \e p. void increase(const Item &i, const Prio &p) { int idx = _iim[i]; - data[idx].prio = p; - bubble_up(idx); + _data[idx].prio = p; + bubbleUp(idx); } - /// \brief Returns if \c item is in, has already been in, or has - /// never been in the heap. + /// \brief Return the state of an item. /// - /// This method returns PRE_HEAP if \c item has never been in the - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP - /// otherwise. In the latter case it is possible that \c item will - /// get back to the heap again. + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. /// \param i The item. State state(const Item &i) const { int s = _iim[i]; @@ -405,11 +410,11 @@ return State(s); } - /// \brief Sets the state of the \c item in the heap. + /// \brief Set the state of an item in the heap. /// - /// Sets the state of the \c item in the heap. It can be used to - /// manually clear the heap when it is important to achive the - /// better time complexity. + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. /// \param i The item. /// \param st The state. It should not be \c IN_HEAP. void state(const Item& i, State st) {