lemon/radix_heap.h
changeset 709 0747f332c478
parent 683 9f529abcaebf
child 710 f1fe0ddad6f7
     1.1 --- a/lemon/radix_heap.h	Thu Jun 11 23:13:24 2009 +0200
     1.2 +++ b/lemon/radix_heap.h	Wed Jul 08 17:21:30 2009 +0200
     1.3 @@ -21,7 +21,7 @@
     1.4  
     1.5  ///\ingroup auxdat
     1.6  ///\file
     1.7 -///\brief Radix Heap implementation.
     1.8 +///\brief Radix heap implementation.
     1.9  
    1.10  #include <vector>
    1.11  #include <lemon/error.h>
    1.12 @@ -29,37 +29,35 @@
    1.13  namespace lemon {
    1.14  
    1.15  
    1.16 -  /// \ingroup auxdata
    1.17 +  /// \ingroup auxdat
    1.18    ///
    1.19 -  /// \brief A Radix Heap implementation.
    1.20 +  /// \brief Radix heap data structure.
    1.21    ///
    1.22 -  /// This class implements the \e radix \e heap data structure. A \e heap
    1.23 -  /// is a data structure for storing items with specified values called \e
    1.24 -  /// priorities in such a way that finding the item with minimum priority is
    1.25 -  /// efficient. This heap type can store only items with \e int priority.
    1.26 -  /// In a heap one can change the priority of an item, add or erase an
    1.27 -  /// item, but the priority cannot be decreased under the last removed
    1.28 -  /// item's priority.
    1.29 +  /// This class implements the \e radix \e heap data structure.
    1.30 +  /// It practically conforms to the \ref concepts::Heap "heap concept",
    1.31 +  /// but it has some limitations due its special implementation.
    1.32 +  /// The type of the priorities must be \c int and the priority of an
    1.33 +  /// item cannot be decreased under the priority of the last removed item.
    1.34    ///
    1.35 -  /// \param IM A read and writable Item int map, used internally
    1.36 -  /// to handle the cross references.
    1.37 -  ///
    1.38 -  /// \see BinHeap
    1.39 -  /// \see Dijkstra
    1.40 +  /// \tparam IM A read-writable item map with \c int values, used
    1.41 +  /// internally to handle the cross references.
    1.42    template <typename IM>
    1.43    class RadixHeap {
    1.44  
    1.45    public:
    1.46 -    typedef typename IM::Key Item;
    1.47 +
    1.48 +    /// Type of the item-int map.
    1.49 +    typedef IM ItemIntMap;
    1.50 +    /// Type of the priorities.
    1.51      typedef int Prio;
    1.52 -    typedef IM ItemIntMap;
    1.53 +    /// Type of the items stored in the heap.
    1.54 +    typedef typename ItemIntMap::Key Item;
    1.55  
    1.56      /// \brief Exception thrown by RadixHeap.
    1.57      ///
    1.58 -    /// This Exception is thrown when a smaller priority
    1.59 -    /// is inserted into the \e RadixHeap then the last time erased.
    1.60 +    /// This exception is thrown when an item is inserted into a
    1.61 +    /// RadixHeap with a priority smaller than the last erased one.
    1.62      /// \see RadixHeap
    1.63 -
    1.64      class UnderFlowPriorityError : public Exception {
    1.65      public:
    1.66        virtual const char* what() const throw() {
    1.67 @@ -67,18 +65,18 @@
    1.68        }
    1.69      };
    1.70  
    1.71 -    /// \brief Type to represent the items states.
    1.72 +    /// \brief Type to represent the states of the items.
    1.73      ///
    1.74 -    /// Each Item element have a state associated to it. It may be "in heap",
    1.75 -    /// "pre heap" or "post heap". The latter two are indifferent from the
    1.76 +    /// Each item has a state associated to it. It can be "in heap",
    1.77 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
    1.78      /// heap's point of view, but may be useful to the user.
    1.79      ///
    1.80 -    /// The ItemIntMap \e should be initialized in such way that it maps
    1.81 -    /// PRE_HEAP (-1) to any element to be put in the heap...
    1.82 +    /// The item-int map must be initialized in such way that it assigns
    1.83 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
    1.84      enum State {
    1.85 -      IN_HEAP = 0,
    1.86 -      PRE_HEAP = -1,
    1.87 -      POST_HEAP = -2
    1.88 +      IN_HEAP = 0,    ///< = 0.
    1.89 +      PRE_HEAP = -1,  ///< = -1.
    1.90 +      POST_HEAP = -2  ///< = -2.
    1.91      };
    1.92  
    1.93    private:
    1.94 @@ -101,47 +99,50 @@
    1.95  
    1.96      ItemIntMap &_iim;
    1.97  
    1.98 +  public:
    1.99  
   1.100 -  public:
   1.101 -    /// \brief The constructor.
   1.102 +    /// \brief Constructor.
   1.103      ///
   1.104 -    /// The constructor.
   1.105 -    ///
   1.106 -    /// \param map It should be given to the constructor, since it is used
   1.107 -    /// internally to handle the cross references. The value of the map
   1.108 -    /// should be PRE_HEAP (-1) for each element.
   1.109 -    ///
   1.110 -    /// \param minimal The initial minimal value of the heap.
   1.111 -    /// \param capacity It determines the initial capacity of the heap.
   1.112 -    RadixHeap(ItemIntMap &map, int minimal = 0, int capacity = 0)
   1.113 -      : _iim(map) {
   1.114 -      boxes.push_back(RadixBox(minimal, 1));
   1.115 -      boxes.push_back(RadixBox(minimal + 1, 1));
   1.116 -      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
   1.117 +    /// Constructor.
   1.118 +    /// \param map A map that assigns \c int values to the items.
   1.119 +    /// It is used internally to handle the cross references.
   1.120 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
   1.121 +    /// \param minimum The initial minimum value of the heap.
   1.122 +    /// \param capacity The initial capacity of the heap.
   1.123 +    RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
   1.124 +      : _iim(map)
   1.125 +    {
   1.126 +      boxes.push_back(RadixBox(minimum, 1));
   1.127 +      boxes.push_back(RadixBox(minimum + 1, 1));
   1.128 +      while (lower(boxes.size() - 1, capacity + minimum - 1)) {
   1.129          extend();
   1.130        }
   1.131      }
   1.132  
   1.133 -    /// The number of items stored in the heap.
   1.134 +    /// \brief The number of items stored in the heap.
   1.135      ///
   1.136 -    /// \brief Returns the number of items stored in the heap.
   1.137 +    /// This function returns the number of items stored in the heap.
   1.138      int size() const { return data.size(); }
   1.139 -    /// \brief Checks if the heap stores no items.
   1.140 +
   1.141 +    /// \brief Check if the heap is empty.
   1.142      ///
   1.143 -    /// Returns \c true if and only if the heap stores no items.
   1.144 +    /// This function returns \c true if the heap is empty.
   1.145      bool empty() const { return data.empty(); }
   1.146  
   1.147 -    /// \brief Make empty this heap.
   1.148 +    /// \brief Make the heap empty.
   1.149      ///
   1.150 -    /// Make empty this heap. It does not change the cross reference
   1.151 -    /// map.  If you want to reuse a heap what is not surely empty you
   1.152 -    /// should first clear the heap and after that you should set the
   1.153 -    /// cross reference map for each item to \c PRE_HEAP.
   1.154 -    void clear(int minimal = 0, int capacity = 0) {
   1.155 +    /// This functon makes the heap empty.
   1.156 +    /// It does not change the cross reference map. If you want to reuse
   1.157 +    /// a heap that is not surely empty, you should first clear it and
   1.158 +    /// then you should set the cross reference map to \c PRE_HEAP
   1.159 +    /// for each item.
   1.160 +    /// \param minimum The minimum value of the heap.
   1.161 +    /// \param capacity The capacity of the heap.
   1.162 +    void clear(int minimum = 0, int capacity = 0) {
   1.163        data.clear(); boxes.clear();
   1.164 -      boxes.push_back(RadixBox(minimal, 1));
   1.165 -      boxes.push_back(RadixBox(minimal + 1, 1));
   1.166 -      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
   1.167 +      boxes.push_back(RadixBox(minimum, 1));
   1.168 +      boxes.push_back(RadixBox(minimum + 1, 1));
   1.169 +      while (lower(boxes.size() - 1, capacity + minimum - 1)) {
   1.170          extend();
   1.171        }
   1.172      }
   1.173 @@ -156,7 +157,7 @@
   1.174        return pr >= boxes[box].min + boxes[box].size;
   1.175      }
   1.176  
   1.177 -    /// \brief Remove item from the box list.
   1.178 +    // Remove item from the box list
   1.179      void remove(int index) {
   1.180        if (data[index].prev >= 0) {
   1.181          data[data[index].prev].next = data[index].next;
   1.182 @@ -168,7 +169,7 @@
   1.183        }
   1.184      }
   1.185  
   1.186 -    /// \brief Insert item into the box list.
   1.187 +    // Insert item into the box list
   1.188      void insert(int box, int index) {
   1.189        if (boxes[box].first == -1) {
   1.190          boxes[box].first = index;
   1.191 @@ -182,14 +183,14 @@
   1.192        data[index].box = box;
   1.193      }
   1.194  
   1.195 -    /// \brief Add a new box to the box list.
   1.196 +    // Add a new box to the box list
   1.197      void extend() {
   1.198        int min = boxes.back().min + boxes.back().size;
   1.199        int bs = 2 * boxes.back().size;
   1.200        boxes.push_back(RadixBox(min, bs));
   1.201      }
   1.202  
   1.203 -    /// \brief Move an item up into the proper box.
   1.204 +    // Move an item up into the proper box.
   1.205      void bubble_up(int index) {
   1.206        if (!lower(data[index].box, data[index].prio)) return;
   1.207        remove(index);
   1.208 @@ -197,7 +198,7 @@
   1.209        insert(box, index);
   1.210      }
   1.211  
   1.212 -    /// \brief Find up the proper box for the item with the given prio.
   1.213 +    // Find up the proper box for the item with the given priority
   1.214      int findUp(int start, int pr) {
   1.215        while (lower(start, pr)) {
   1.216          if (++start == int(boxes.size())) {
   1.217 @@ -207,7 +208,7 @@
   1.218        return start;
   1.219      }
   1.220  
   1.221 -    /// \brief Move an item down into the proper box.
   1.222 +    // Move an item down into the proper box
   1.223      void bubble_down(int index) {
   1.224        if (!upper(data[index].box, data[index].prio)) return;
   1.225        remove(index);
   1.226 @@ -215,7 +216,7 @@
   1.227        insert(box, index);
   1.228      }
   1.229  
   1.230 -    /// \brief Find up the proper box for the item with the given prio.
   1.231 +    // Find down the proper box for the item with the given priority
   1.232      int findDown(int start, int pr) {
   1.233        while (upper(start, pr)) {
   1.234          if (--start < 0) throw UnderFlowPriorityError();
   1.235 @@ -223,14 +224,14 @@
   1.236        return start;
   1.237      }
   1.238  
   1.239 -    /// \brief Find the first not empty box.
   1.240 +    // Find the first non-empty box
   1.241      int findFirst() {
   1.242        int first = 0;
   1.243        while (boxes[first].first == -1) ++first;
   1.244        return first;
   1.245      }
   1.246  
   1.247 -    /// \brief Gives back the minimal prio of the box.
   1.248 +    // Gives back the minimum priority of the given box
   1.249      int minValue(int box) {
   1.250        int min = data[boxes[box].first].prio;
   1.251        for (int k = boxes[box].first; k != -1; k = data[k].next) {
   1.252 @@ -239,8 +240,7 @@
   1.253        return min;
   1.254      }
   1.255  
   1.256 -    /// \brief Rearrange the items of the heap and makes the
   1.257 -    /// first box not empty.
   1.258 +    // Rearrange the items of the heap and make the first box non-empty
   1.259      void moveDown() {
   1.260        int box = findFirst();
   1.261        if (box == 0) return;
   1.262 @@ -277,9 +277,12 @@
   1.263  
   1.264      /// \brief Insert an item into the heap with the given priority.
   1.265      ///
   1.266 -    /// Adds \c i to the heap with priority \c p.
   1.267 +    /// This function inserts the given item into the heap with the
   1.268 +    /// given priority.
   1.269      /// \param i The item to insert.
   1.270      /// \param p The priority of the item.
   1.271 +    /// \pre \e i must not be stored in the heap.
   1.272 +    /// \warning This method may throw an \c UnderFlowPriorityException.
   1.273      void push(const Item &i, const Prio &p) {
   1.274        int n = data.size();
   1.275        _iim.set(i, n);
   1.276 @@ -291,27 +294,27 @@
   1.277        insert(box, n);
   1.278      }
   1.279  
   1.280 -    /// \brief Returns the item with minimum priority.
   1.281 +    /// \brief Return the item having minimum priority.
   1.282      ///
   1.283 -    /// This method returns the item with minimum priority.
   1.284 -    /// \pre The heap must be nonempty.
   1.285 +    /// This function returns the item having minimum priority.
   1.286 +    /// \pre The heap must be non-empty.
   1.287      Item top() const {
   1.288        const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
   1.289        return data[boxes[0].first].item;
   1.290      }
   1.291  
   1.292 -    /// \brief Returns the minimum priority.
   1.293 +    /// \brief The minimum priority.
   1.294      ///
   1.295 -    /// It returns the minimum priority.
   1.296 -    /// \pre The heap must be nonempty.
   1.297 +    /// This function returns the minimum priority.
   1.298 +    /// \pre The heap must be non-empty.
   1.299      Prio prio() const {
   1.300        const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
   1.301        return data[boxes[0].first].prio;
   1.302       }
   1.303  
   1.304 -    /// \brief Deletes the item with minimum priority.
   1.305 +    /// \brief Remove the item having minimum priority.
   1.306      ///
   1.307 -    /// This method deletes the item with minimum priority.
   1.308 +    /// This function removes the item having minimum priority.
   1.309      /// \pre The heap must be non-empty.
   1.310      void pop() {
   1.311        moveDown();
   1.312 @@ -321,11 +324,12 @@
   1.313        relocate_last(index);
   1.314      }
   1.315  
   1.316 -    /// \brief Deletes \c i from the heap.
   1.317 +    /// \brief Remove the given item from the heap.
   1.318      ///
   1.319 -    /// This method deletes item \c i from the heap, if \c i was
   1.320 -    /// already stored in the heap.
   1.321 -    /// \param i The item to erase.
   1.322 +    /// This function removes the given item from the heap if it is
   1.323 +    /// already stored.
   1.324 +    /// \param i The item to delete.
   1.325 +    /// \pre \e i must be in the heap.
   1.326      void erase(const Item &i) {
   1.327        int index = _iim[i];
   1.328        _iim[i] = POST_HEAP;
   1.329 @@ -333,24 +337,26 @@
   1.330        relocate_last(index);
   1.331     }
   1.332  
   1.333 -    /// \brief Returns the priority of \c i.
   1.334 +    /// \brief The priority of the given item.
   1.335      ///
   1.336 -    /// This function returns the priority of item \c i.
   1.337 -    /// \pre \c i must be in the heap.
   1.338 +    /// This function returns the priority of the given item.
   1.339      /// \param i The item.
   1.340 +    /// \pre \e i must be in the heap.
   1.341      Prio operator[](const Item &i) const {
   1.342        int idx = _iim[i];
   1.343        return data[idx].prio;
   1.344      }
   1.345  
   1.346 -    /// \brief \c i gets to the heap with priority \c p independently
   1.347 -    /// if \c i was already there.
   1.348 +    /// \brief Set the priority of an item or insert it, if it is
   1.349 +    /// not stored in the heap.
   1.350      ///
   1.351 -    /// This method calls \ref push(\c i, \c p) if \c i is not stored
   1.352 -    /// in the heap and sets the priority of \c i to \c p otherwise.
   1.353 -    /// It may throw an \e UnderFlowPriorityException.
   1.354 +    /// This method sets the priority of the given item if it is
   1.355 +    /// already stored in the heap. Otherwise it inserts the given
   1.356 +    /// item into the heap with the given priority.
   1.357      /// \param i The item.
   1.358      /// \param p The priority.
   1.359 +    /// \pre \e i must be in the heap.
   1.360 +    /// \warning This method may throw an \c UnderFlowPriorityException.
   1.361      void set(const Item &i, const Prio &p) {
   1.362        int idx = _iim[i];
   1.363        if( idx < 0 ) {
   1.364 @@ -365,39 +371,38 @@
   1.365        }
   1.366      }
   1.367  
   1.368 -
   1.369 -    /// \brief Decreases the priority of \c i to \c p.
   1.370 +    /// \brief Decrease the priority of an item to the given value.
   1.371      ///
   1.372 -    /// This method decreases the priority of item \c i to \c p.
   1.373 -    /// \pre \c i must be stored in the heap with priority at least \c p, and
   1.374 -    /// \c should be greater or equal to the last removed item's priority.
   1.375 +    /// This function decreases the priority of an item to the given value.
   1.376      /// \param i The item.
   1.377      /// \param p The priority.
   1.378 +    /// \pre \e i must be stored in the heap with priority at least \e p.
   1.379 +    /// \warning This method may throw an \c UnderFlowPriorityException.
   1.380      void decrease(const Item &i, const Prio &p) {
   1.381        int idx = _iim[i];
   1.382        data[idx].prio = p;
   1.383        bubble_down(idx);
   1.384      }
   1.385  
   1.386 -    /// \brief Increases the priority of \c i to \c p.
   1.387 +    /// \brief Increase the priority of an item to the given value.
   1.388      ///
   1.389 -    /// This method sets the priority of item \c i to \c p.
   1.390 -    /// \pre \c i must be stored in the heap with priority at most \c p
   1.391 +    /// This function increases the priority of an item to the given value.
   1.392      /// \param i The item.
   1.393      /// \param p The priority.
   1.394 +    /// \pre \e i must be stored in the heap with priority at most \e p.
   1.395      void increase(const Item &i, const Prio &p) {
   1.396        int idx = _iim[i];
   1.397        data[idx].prio = p;
   1.398        bubble_up(idx);
   1.399      }
   1.400  
   1.401 -    /// \brief Returns if \c item is in, has already been in, or has
   1.402 -    /// never been in the heap.
   1.403 +    /// \brief Return the state of an item.
   1.404      ///
   1.405 -    /// This method returns PRE_HEAP if \c item has never been in the
   1.406 -    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
   1.407 -    /// otherwise. In the latter case it is possible that \c item will
   1.408 -    /// get back to the heap again.
   1.409 +    /// This method returns \c PRE_HEAP if the given item has never
   1.410 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
   1.411 +    /// and \c POST_HEAP otherwise.
   1.412 +    /// In the latter case it is possible that the item will get back
   1.413 +    /// to the heap again.
   1.414      /// \param i The item.
   1.415      State state(const Item &i) const {
   1.416        int s = _iim[i];
   1.417 @@ -405,11 +410,11 @@
   1.418        return State(s);
   1.419      }
   1.420  
   1.421 -    /// \brief Sets the state of the \c item in the heap.
   1.422 +    /// \brief Set the state of an item in the heap.
   1.423      ///
   1.424 -    /// Sets the state of the \c item in the heap. It can be used to
   1.425 -    /// manually clear the heap when it is important to achive the
   1.426 -    /// better time complexity.
   1.427 +    /// This function sets the state of the given item in the heap.
   1.428 +    /// It can be used to manually clear the heap when it is important
   1.429 +    /// to achive better time complexity.
   1.430      /// \param i The item.
   1.431      /// \param st The state. It should not be \c IN_HEAP.
   1.432      void state(const Item& i, State st) {