diff --git a/lemon/fourary_heap.h b/lemon/fourary_heap.h --- a/lemon/fourary_heap.h +++ b/lemon/fourary_heap.h @@ -1,8 +1,8 @@ -/* -*- C++ -*- +/* -*- mode: C++; indent-tabs-mode: nil; -*- * - * This file is a part of LEMON, a generic C++ optimization library + * This file is a part of LEMON, a generic C++ optimization library. * - * Copyright (C) 2003-2008 + * Copyright (C) 2003-2009 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport * (Egervary Research Group on Combinatorial Optimization, EGRES). * @@ -19,159 +19,158 @@ #ifndef LEMON_FOURARY_HEAP_H #define LEMON_FOURARY_HEAP_H -///\ingroup auxdat +///\ingroup heaps ///\file -///\brief 4ary Heap implementation. +///\brief Fourary heap implementation. -#include #include #include #include namespace lemon { - ///\ingroup auxdat + /// \ingroup heaps /// - ///\brief A 4ary Heap implementation. + ///\brief Fourary heap data structure. /// - ///This class implements the \e 4ary \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 Compare 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 fourary \e heap data structure. + /// It fully conforms to the \ref concepts::Heap "heap concept". /// - ///\param _Prio Type of the priority of the items. - ///\param _ItemIntMap A read and writable Item int map, used internally - ///to handle the cross references. - ///\param _Compare A class for the ordering of the priorities. The - ///default is \c std::less<_Prio>. + /// The fourary heap is a specialization of the \ref KaryHeap "K-ary heap" + /// for K=4. It is similar to the \ref BinHeap "binary heap", + /// but its nodes have at most four children, instead of two. /// - ///\sa FibHeap - ///\sa Dijkstra - ///\author Dorian Batha + /// \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. + /// + ///\sa BinHeap + ///\sa KaryHeap +#ifdef DOXYGEN + template +#else + template > +#endif + class FouraryHeap { + public: + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef PR Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Type of the item-priority pairs. + typedef std::pair Pair; + /// Functor type for comparing the priorities. + typedef CMP Compare; - template > - - class FouraryHeap { - - public: - ///\e - typedef _ItemIntMap ItemIntMap; - ///\e - typedef _Prio Prio; - ///\e - typedef typename ItemIntMap::Key Item; - ///\e - typedef std::pair Pair; - ///\e - typedef _Compare 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 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: - std::vector data; - Compare comp; - ItemIntMap &iim; + std::vector _data; + Compare _comp; + ItemIntMap &_iim; public: - /// \brief The constructor. + /// \brief Constructor. /// - /// The constructor. - /// \param _iim 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. - explicit FouraryHeap(ItemIntMap &_iim) : iim(_iim) {} + /// 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 FouraryHeap(ItemIntMap &map) : _iim(map) {} - /// \brief The constructor. + /// \brief Constructor. /// - /// The constructor. - /// \param _iim 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. + /// \param comp The function object used for comparing the priorities. + FouraryHeap(ItemIntMap &map, const Compare &comp) + : _iim(map), _comp(comp) {} + + /// \brief The number of items stored in the heap. /// - /// \param _comp The comparator function object. - FouraryHeap(ItemIntMap &_iim, const Compare &_comp) - : iim(_iim), comp(_comp) {} + /// This function returns the number of items stored in the heap. + int size() const { return _data.size(); } - /// The number of items stored in the heap. + /// \brief Check if the heap is empty. /// - /// \brief Returns the number of items stored in the heap. - int size() const { return data.size(); } + /// This function returns \c true if the heap is empty. + bool empty() const { return _data.empty(); } - /// \brief Checks if the heap stores no items. + /// \brief Make the heap empty. /// - /// Returns \c true if and only if the heap stores no items. - bool empty() const { return data.empty(); } - - /// \brief Make empty this heap. - /// - /// 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. - void clear() { data.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() { _data.clear(); } private: static int parent(int i) { return (i-1)/4; } static int firstChild(int i) { return 4*i+1; } bool less(const Pair &p1, const Pair &p2) const { - return comp(p1.second, p2.second); + return _comp(p1.second, p2.second); } - int find_min(const int child, const int length) { + int findMin(const int child, const int length) { int min=child; if( child+30 && less(p,data[par]) ) { - move(data[par],hole); + while( hole>0 && less(p,_data[par]) ) { + move(_data[par],hole); hole = par; par = parent(hole); } move(p, hole); } - void bubble_down(int hole, Pair p, int length) { + void bubbleDown(int hole, Pair p, int length) { int child = firstChild(hole); while( child1 ) { - child = find_min(child,length); - if( !less(data[child], p) ) + child = findMin(child,length); + if( !less(_data[child], p) ) goto ok; - move(data[child], hole); + move(_data[child], hole); hole = child; child = firstChild(hole); } @@ -180,142 +179,143 @@ } void move(const Pair &p, int i) { - data[i] = p; - iim.set(p.first, i); + _data[i] = p; + _iim.set(p.first, i); } 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) { - int n = data.size(); - data.resize(n+1); - bubble_up(n, p); + int n = _data.size(); + _data.resize(n+1); + bubbleUp(n, p); } - /// \brief Insert an item into the heap with the given heap. + /// \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) { push(Pair(i,p)); } - /// \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. - Item top() const { return data[0].first; } + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. + Item top() const { return _data[0].first; } - /// \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. - Prio prio() const { return data[0].second; } + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. + Prio prio() const { return _data[0].second; } - /// \brief Deletes the item with minimum priority relative to \c Compare. + /// \brief Remove the item having minimum priority. /// - /// 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() { - int n = data.size()-1; - iim.set(data[0].first, POST_HEAP); - if (n>0) bubble_down(0, data[n], n); - data.pop_back(); + int n = _data.size()-1; + _iim.set(_data[0].first, POST_HEAP); + if (n>0) 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); + int h = _iim[i]; + int n = _data.size()-1; + _iim.set(_data[h].first, POST_HEAP); if( h=0) s=0; 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) { @@ -323,24 +323,25 @@ case POST_HEAP: case PRE_HEAP: if (state(i) == IN_HEAP) erase(i); - iim[i] = st; + _iim[i] = st; break; case IN_HEAP: break; } } - /// \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]); - iim.set(j, idx); - data[idx].first = j; + int idx = _iim[i]; + _iim.set(i, _iim[j]); + _iim.set(j, idx); + _data[idx].first = j; } }; // class FouraryHeap