lemon/bucket_heap.h
changeset 683 9f529abcaebf
parent 682 bb8c4cd57900
child 709 0747f332c478
     1.1 --- a/lemon/bucket_heap.h	Thu Jun 11 22:16:11 2009 +0200
     1.2 +++ b/lemon/bucket_heap.h	Thu Jun 11 23:13:24 2009 +0200
     1.3 @@ -31,7 +31,7 @@
     1.4  
     1.5    namespace _bucket_heap_bits {
     1.6  
     1.7 -    template <bool minimize>
     1.8 +    template <bool MIN>
     1.9      struct DirectionTraits {
    1.10        static bool less(int left, int right) {
    1.11          return left < right;
    1.12 @@ -65,26 +65,27 @@
    1.13    /// \f$ [0..C) \f$ range a list of items. So it should be used only when
    1.14    /// the priorities are small. It is not intended to use as dijkstra heap.
    1.15    ///
    1.16 -  /// \param _ItemIntMap A read and writable Item int map, used internally
    1.17 +  /// \param IM A read and write Item int map, used internally
    1.18    /// to handle the cross references.
    1.19 -  /// \param minimize If the given parameter is true then the heap gives back
    1.20 -  /// the lowest priority.
    1.21 -  template <typename _ItemIntMap, bool minimize = true>
    1.22 +  /// \param MIN If the given parameter is false then instead of the
    1.23 +  /// minimum value the maximum can be retrivied with the top() and
    1.24 +  /// prio() member functions.
    1.25 +  template <typename IM, bool MIN = true>
    1.26    class BucketHeap {
    1.27  
    1.28    public:
    1.29      /// \e
    1.30 -    typedef typename _ItemIntMap::Key Item;
    1.31 +    typedef typename IM::Key Item;
    1.32      /// \e
    1.33      typedef int Prio;
    1.34      /// \e
    1.35      typedef std::pair<Item, Prio> Pair;
    1.36      /// \e
    1.37 -    typedef _ItemIntMap ItemIntMap;
    1.38 +    typedef IM ItemIntMap;
    1.39  
    1.40    private:
    1.41  
    1.42 -    typedef _bucket_heap_bits::DirectionTraits<minimize> Direction;
    1.43 +    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
    1.44  
    1.45    public:
    1.46  
    1.47 @@ -94,32 +95,32 @@
    1.48      /// "pre heap" or "post heap". The latter two are indifferent from the
    1.49      /// heap's point of view, but may be useful to the user.
    1.50      ///
    1.51 -    /// The ItemIntMap \e should be initialized in such way that it maps
    1.52 -    /// PRE_HEAP (-1) to any element to be put in the heap...
    1.53 +    /// The item-int map must be initialized in such way that it assigns
    1.54 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
    1.55      enum State {
    1.56 -      IN_HEAP = 0,
    1.57 -      PRE_HEAP = -1,
    1.58 -      POST_HEAP = -2
    1.59 +      IN_HEAP = 0,    ///< = 0.
    1.60 +      PRE_HEAP = -1,  ///< = -1.
    1.61 +      POST_HEAP = -2  ///< = -2.
    1.62      };
    1.63  
    1.64    public:
    1.65      /// \brief The constructor.
    1.66      ///
    1.67      /// The constructor.
    1.68 -    /// \param _index should be given to the constructor, since it is used
    1.69 +    /// \param map should be given to the constructor, since it is used
    1.70      /// internally to handle the cross references. The value of the map
    1.71      /// should be PRE_HEAP (-1) for each element.
    1.72 -    explicit BucketHeap(ItemIntMap &_index) : index(_index), minimal(0) {}
    1.73 +    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
    1.74  
    1.75      /// The number of items stored in the heap.
    1.76      ///
    1.77      /// \brief Returns the number of items stored in the heap.
    1.78 -    int size() const { return data.size(); }
    1.79 +    int size() const { return _data.size(); }
    1.80  
    1.81      /// \brief Checks if the heap stores no items.
    1.82      ///
    1.83      /// Returns \c true if and only if the heap stores no items.
    1.84 -    bool empty() const { return data.empty(); }
    1.85 +    bool empty() const { return _data.empty(); }
    1.86  
    1.87      /// \brief Make empty this heap.
    1.88      ///
    1.89 @@ -128,48 +129,48 @@
    1.90      /// should first clear the heap and after that you should set the
    1.91      /// cross reference map for each item to \c PRE_HEAP.
    1.92      void clear() {
    1.93 -      data.clear(); first.clear(); minimal = 0;
    1.94 +      _data.clear(); _first.clear(); _minimum = 0;
    1.95      }
    1.96  
    1.97    private:
    1.98  
    1.99      void relocate_last(int idx) {
   1.100 -      if (idx + 1 < int(data.size())) {
   1.101 -        data[idx] = data.back();
   1.102 -        if (data[idx].prev != -1) {
   1.103 -          data[data[idx].prev].next = idx;
   1.104 +      if (idx + 1 < int(_data.size())) {
   1.105 +        _data[idx] = _data.back();
   1.106 +        if (_data[idx].prev != -1) {
   1.107 +          _data[_data[idx].prev].next = idx;
   1.108          } else {
   1.109 -          first[data[idx].value] = idx;
   1.110 +          _first[_data[idx].value] = idx;
   1.111          }
   1.112 -        if (data[idx].next != -1) {
   1.113 -          data[data[idx].next].prev = idx;
   1.114 +        if (_data[idx].next != -1) {
   1.115 +          _data[_data[idx].next].prev = idx;
   1.116          }
   1.117 -        index[data[idx].item] = idx;
   1.118 +        _iim[_data[idx].item] = idx;
   1.119        }
   1.120 -      data.pop_back();
   1.121 +      _data.pop_back();
   1.122      }
   1.123  
   1.124      void unlace(int idx) {
   1.125 -      if (data[idx].prev != -1) {
   1.126 -        data[data[idx].prev].next = data[idx].next;
   1.127 +      if (_data[idx].prev != -1) {
   1.128 +        _data[_data[idx].prev].next = _data[idx].next;
   1.129        } else {
   1.130 -        first[data[idx].value] = data[idx].next;
   1.131 +        _first[_data[idx].value] = _data[idx].next;
   1.132        }
   1.133 -      if (data[idx].next != -1) {
   1.134 -        data[data[idx].next].prev = data[idx].prev;
   1.135 +      if (_data[idx].next != -1) {
   1.136 +        _data[_data[idx].next].prev = _data[idx].prev;
   1.137        }
   1.138      }
   1.139  
   1.140      void lace(int idx) {
   1.141 -      if (int(first.size()) <= data[idx].value) {
   1.142 -        first.resize(data[idx].value + 1, -1);
   1.143 +      if (int(_first.size()) <= _data[idx].value) {
   1.144 +        _first.resize(_data[idx].value + 1, -1);
   1.145        }
   1.146 -      data[idx].next = first[data[idx].value];
   1.147 -      if (data[idx].next != -1) {
   1.148 -        data[data[idx].next].prev = idx;
   1.149 +      _data[idx].next = _first[_data[idx].value];
   1.150 +      if (_data[idx].next != -1) {
   1.151 +        _data[_data[idx].next].prev = idx;
   1.152        }
   1.153 -      first[data[idx].value] = idx;
   1.154 -      data[idx].prev = -1;
   1.155 +      _first[_data[idx].value] = idx;
   1.156 +      _data[idx].prev = -1;
   1.157      }
   1.158  
   1.159    public:
   1.160 @@ -187,12 +188,12 @@
   1.161      /// \param i The item to insert.
   1.162      /// \param p The priority of the item.
   1.163      void push(const Item &i, const Prio &p) {
   1.164 -      int idx = data.size();
   1.165 -      index[i] = idx;
   1.166 -      data.push_back(BucketItem(i, p));
   1.167 +      int idx = _data.size();
   1.168 +      _iim[i] = idx;
   1.169 +      _data.push_back(BucketItem(i, p));
   1.170        lace(idx);
   1.171 -      if (Direction::less(p, minimal)) {
   1.172 -        minimal = p;
   1.173 +      if (Direction::less(p, _minimum)) {
   1.174 +        _minimum = p;
   1.175        }
   1.176      }
   1.177  
   1.178 @@ -201,10 +202,10 @@
   1.179      /// This method returns the item with minimum priority.
   1.180      /// \pre The heap must be nonempty.
   1.181      Item top() const {
   1.182 -      while (first[minimal] == -1) {
   1.183 -        Direction::increase(minimal);
   1.184 +      while (_first[_minimum] == -1) {
   1.185 +        Direction::increase(_minimum);
   1.186        }
   1.187 -      return data[first[minimal]].item;
   1.188 +      return _data[_first[_minimum]].item;
   1.189      }
   1.190  
   1.191      /// \brief Returns the minimum priority.
   1.192 @@ -212,10 +213,10 @@
   1.193      /// It returns the minimum priority.
   1.194      /// \pre The heap must be nonempty.
   1.195      Prio prio() const {
   1.196 -      while (first[minimal] == -1) {
   1.197 -        Direction::increase(minimal);
   1.198 +      while (_first[_minimum] == -1) {
   1.199 +        Direction::increase(_minimum);
   1.200        }
   1.201 -      return minimal;
   1.202 +      return _minimum;
   1.203      }
   1.204  
   1.205      /// \brief Deletes the item with minimum priority.
   1.206 @@ -223,11 +224,11 @@
   1.207      /// This method deletes the item with minimum priority from the heap.
   1.208      /// \pre The heap must be non-empty.
   1.209      void pop() {
   1.210 -      while (first[minimal] == -1) {
   1.211 -        Direction::increase(minimal);
   1.212 +      while (_first[_minimum] == -1) {
   1.213 +        Direction::increase(_minimum);
   1.214        }
   1.215 -      int idx = first[minimal];
   1.216 -      index[data[idx].item] = -2;
   1.217 +      int idx = _first[_minimum];
   1.218 +      _iim[_data[idx].item] = -2;
   1.219        unlace(idx);
   1.220        relocate_last(idx);
   1.221      }
   1.222 @@ -238,8 +239,8 @@
   1.223      /// already stored in the heap.
   1.224      /// \param i The item to erase.
   1.225      void erase(const Item &i) {
   1.226 -      int idx = index[i];
   1.227 -      index[data[idx].item] = -2;
   1.228 +      int idx = _iim[i];
   1.229 +      _iim[_data[idx].item] = -2;
   1.230        unlace(idx);
   1.231        relocate_last(idx);
   1.232      }
   1.233 @@ -251,8 +252,8 @@
   1.234      /// \pre \c i must be in the heap.
   1.235      /// \param i The item.
   1.236      Prio operator[](const Item &i) const {
   1.237 -      int idx = index[i];
   1.238 -      return data[idx].value;
   1.239 +      int idx = _iim[i];
   1.240 +      return _data[idx].value;
   1.241      }
   1.242  
   1.243      /// \brief \c i gets to the heap with priority \c p independently
   1.244 @@ -263,10 +264,10 @@
   1.245      /// \param i The item.
   1.246      /// \param p The priority.
   1.247      void set(const Item &i, const Prio &p) {
   1.248 -      int idx = index[i];
   1.249 +      int idx = _iim[i];
   1.250        if (idx < 0) {
   1.251          push(i, p);
   1.252 -      } else if (Direction::less(p, data[idx].value)) {
   1.253 +      } else if (Direction::less(p, _data[idx].value)) {
   1.254          decrease(i, p);
   1.255        } else {
   1.256          increase(i, p);
   1.257 @@ -281,11 +282,11 @@
   1.258      /// \param i The item.
   1.259      /// \param p The priority.
   1.260      void decrease(const Item &i, const Prio &p) {
   1.261 -      int idx = index[i];
   1.262 +      int idx = _iim[i];
   1.263        unlace(idx);
   1.264 -      data[idx].value = p;
   1.265 -      if (Direction::less(p, minimal)) {
   1.266 -        minimal = p;
   1.267 +      _data[idx].value = p;
   1.268 +      if (Direction::less(p, _minimum)) {
   1.269 +        _minimum = p;
   1.270        }
   1.271        lace(idx);
   1.272      }
   1.273 @@ -298,9 +299,9 @@
   1.274      /// \param i The item.
   1.275      /// \param p The priority.
   1.276      void increase(const Item &i, const Prio &p) {
   1.277 -      int idx = index[i];
   1.278 +      int idx = _iim[i];
   1.279        unlace(idx);
   1.280 -      data[idx].value = p;
   1.281 +      _data[idx].value = p;
   1.282        lace(idx);
   1.283      }
   1.284  
   1.285 @@ -313,7 +314,7 @@
   1.286      /// get back to the heap again.
   1.287      /// \param i The item.
   1.288      State state(const Item &i) const {
   1.289 -      int idx = index[i];
   1.290 +      int idx = _iim[i];
   1.291        if (idx >= 0) idx = 0;
   1.292        return State(idx);
   1.293      }
   1.294 @@ -332,7 +333,7 @@
   1.295          if (state(i) == IN_HEAP) {
   1.296            erase(i);
   1.297          }
   1.298 -        index[i] = st;
   1.299 +        _iim[i] = st;
   1.300          break;
   1.301        case IN_HEAP:
   1.302          break;
   1.303 @@ -351,10 +352,10 @@
   1.304        int prev, next;
   1.305      };
   1.306  
   1.307 -    ItemIntMap& index;
   1.308 -    std::vector<int> first;
   1.309 -    std::vector<BucketItem> data;
   1.310 -    mutable int minimal;
   1.311 +    ItemIntMap& _iim;
   1.312 +    std::vector<int> _first;
   1.313 +    std::vector<BucketItem> _data;
   1.314 +    mutable int _minimum;
   1.315  
   1.316    }; // class BucketHeap
   1.317  
   1.318 @@ -370,24 +371,25 @@
   1.319    /// other way it does not support erasing each elements just the
   1.320    /// minimal and it does not supports key increasing, decreasing.
   1.321    ///
   1.322 -  /// \param _ItemIntMap A read and writable Item int map, used internally
   1.323 +  /// \param IM A read and write Item int map, used internally
   1.324    /// to handle the cross references.
   1.325 -  /// \param minimize If the given parameter is true then the heap gives back
   1.326 -  /// the lowest priority.
   1.327 +  /// \param MIN If the given parameter is false then instead of the
   1.328 +  /// minimum value the maximum can be retrivied with the top() and
   1.329 +  /// prio() member functions.
   1.330    ///
   1.331    /// \sa BucketHeap
   1.332 -  template <typename _ItemIntMap, bool minimize = true >
   1.333 +  template <typename IM, bool MIN = true >
   1.334    class SimpleBucketHeap {
   1.335  
   1.336    public:
   1.337 -    typedef typename _ItemIntMap::Key Item;
   1.338 +    typedef typename IM::Key Item;
   1.339      typedef int Prio;
   1.340      typedef std::pair<Item, Prio> Pair;
   1.341 -    typedef _ItemIntMap ItemIntMap;
   1.342 +    typedef IM ItemIntMap;
   1.343  
   1.344    private:
   1.345  
   1.346 -    typedef _bucket_heap_bits::DirectionTraits<minimize> Direction;
   1.347 +    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
   1.348  
   1.349    public:
   1.350  
   1.351 @@ -397,12 +399,12 @@
   1.352      /// "pre heap" or "post heap". The latter two are indifferent from the
   1.353      /// heap's point of view, but may be useful to the user.
   1.354      ///
   1.355 -    /// The ItemIntMap \e should be initialized in such way that it maps
   1.356 -    /// PRE_HEAP (-1) to any element to be put in the heap...
   1.357 +    /// The item-int map must be initialized in such way that it assigns
   1.358 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   1.359      enum State {
   1.360 -      IN_HEAP = 0,
   1.361 -      PRE_HEAP = -1,
   1.362 -      POST_HEAP = -2
   1.363 +      IN_HEAP = 0,    ///< = 0.
   1.364 +      PRE_HEAP = -1,  ///< = -1.
   1.365 +      POST_HEAP = -2  ///< = -2.
   1.366      };
   1.367  
   1.368    public:
   1.369 @@ -410,21 +412,21 @@
   1.370      /// \brief The constructor.
   1.371      ///
   1.372      /// The constructor.
   1.373 -    /// \param _index should be given to the constructor, since it is used
   1.374 +    /// \param map should be given to the constructor, since it is used
   1.375      /// internally to handle the cross references. The value of the map
   1.376      /// should be PRE_HEAP (-1) for each element.
   1.377 -    explicit SimpleBucketHeap(ItemIntMap &_index)
   1.378 -      : index(_index), free(-1), num(0), minimal(0) {}
   1.379 +    explicit SimpleBucketHeap(ItemIntMap &map)
   1.380 +      : _iim(map), _free(-1), _num(0), _minimum(0) {}
   1.381  
   1.382      /// \brief Returns the number of items stored in the heap.
   1.383      ///
   1.384      /// The number of items stored in the heap.
   1.385 -    int size() const { return num; }
   1.386 +    int size() const { return _num; }
   1.387  
   1.388      /// \brief Checks if the heap stores no items.
   1.389      ///
   1.390      /// Returns \c true if and only if the heap stores no items.
   1.391 -    bool empty() const { return num == 0; }
   1.392 +    bool empty() const { return _num == 0; }
   1.393  
   1.394      /// \brief Make empty this heap.
   1.395      ///
   1.396 @@ -433,7 +435,7 @@
   1.397      /// should first clear the heap and after that you should set the
   1.398      /// cross reference map for each item to \c PRE_HEAP.
   1.399      void clear() {
   1.400 -      data.clear(); first.clear(); free = -1; num = 0; minimal = 0;
   1.401 +      _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
   1.402      }
   1.403  
   1.404      /// \brief Insert a pair of item and priority into the heap.
   1.405 @@ -451,22 +453,22 @@
   1.406      /// \param p The priority of the item.
   1.407      void push(const Item &i, const Prio &p) {
   1.408        int idx;
   1.409 -      if (free == -1) {
   1.410 -        idx = data.size();
   1.411 -        data.push_back(BucketItem(i));
   1.412 +      if (_free == -1) {
   1.413 +        idx = _data.size();
   1.414 +        _data.push_back(BucketItem(i));
   1.415        } else {
   1.416 -        idx = free;
   1.417 -        free = data[idx].next;
   1.418 -        data[idx].item = i;
   1.419 +        idx = _free;
   1.420 +        _free = _data[idx].next;
   1.421 +        _data[idx].item = i;
   1.422        }
   1.423 -      index[i] = idx;
   1.424 -      if (p >= int(first.size())) first.resize(p + 1, -1);
   1.425 -      data[idx].next = first[p];
   1.426 -      first[p] = idx;
   1.427 -      if (Direction::less(p, minimal)) {
   1.428 -        minimal = p;
   1.429 +      _iim[i] = idx;
   1.430 +      if (p >= int(_first.size())) _first.resize(p + 1, -1);
   1.431 +      _data[idx].next = _first[p];
   1.432 +      _first[p] = idx;
   1.433 +      if (Direction::less(p, _minimum)) {
   1.434 +        _minimum = p;
   1.435        }
   1.436 -      ++num;
   1.437 +      ++_num;
   1.438      }
   1.439  
   1.440      /// \brief Returns the item with minimum priority.
   1.441 @@ -474,10 +476,10 @@
   1.442      /// This method returns the item with minimum priority.
   1.443      /// \pre The heap must be nonempty.
   1.444      Item top() const {
   1.445 -      while (first[minimal] == -1) {
   1.446 -        Direction::increase(minimal);
   1.447 +      while (_first[_minimum] == -1) {
   1.448 +        Direction::increase(_minimum);
   1.449        }
   1.450 -      return data[first[minimal]].item;
   1.451 +      return _data[_first[_minimum]].item;
   1.452      }
   1.453  
   1.454      /// \brief Returns the minimum priority.
   1.455 @@ -485,10 +487,10 @@
   1.456      /// It returns the minimum priority.
   1.457      /// \pre The heap must be nonempty.
   1.458      Prio prio() const {
   1.459 -      while (first[minimal] == -1) {
   1.460 -        Direction::increase(minimal);
   1.461 +      while (_first[_minimum] == -1) {
   1.462 +        Direction::increase(_minimum);
   1.463        }
   1.464 -      return minimal;
   1.465 +      return _minimum;
   1.466      }
   1.467  
   1.468      /// \brief Deletes the item with minimum priority.
   1.469 @@ -496,15 +498,15 @@
   1.470      /// This method deletes the item with minimum priority from the heap.
   1.471      /// \pre The heap must be non-empty.
   1.472      void pop() {
   1.473 -      while (first[minimal] == -1) {
   1.474 -        Direction::increase(minimal);
   1.475 +      while (_first[_minimum] == -1) {
   1.476 +        Direction::increase(_minimum);
   1.477        }
   1.478 -      int idx = first[minimal];
   1.479 -      index[data[idx].item] = -2;
   1.480 -      first[minimal] = data[idx].next;
   1.481 -      data[idx].next = free;
   1.482 -      free = idx;
   1.483 -      --num;
   1.484 +      int idx = _first[_minimum];
   1.485 +      _iim[_data[idx].item] = -2;
   1.486 +      _first[_minimum] = _data[idx].next;
   1.487 +      _data[idx].next = _free;
   1.488 +      _free = idx;
   1.489 +      --_num;
   1.490      }
   1.491  
   1.492      /// \brief Returns the priority of \c i.
   1.493 @@ -516,13 +518,13 @@
   1.494      /// \pre \c i must be in the heap.
   1.495      /// \param i The item.
   1.496      Prio operator[](const Item &i) const {
   1.497 -      for (int k = 0; k < first.size(); ++k) {
   1.498 -        int idx = first[k];
   1.499 +      for (int k = 0; k < _first.size(); ++k) {
   1.500 +        int idx = _first[k];
   1.501          while (idx != -1) {
   1.502 -          if (data[idx].item == i) {
   1.503 +          if (_data[idx].item == i) {
   1.504              return k;
   1.505            }
   1.506 -          idx = data[idx].next;
   1.507 +          idx = _data[idx].next;
   1.508          }
   1.509        }
   1.510        return -1;
   1.511 @@ -537,7 +539,7 @@
   1.512      /// get back to the heap again.
   1.513      /// \param i The item.
   1.514      State state(const Item &i) const {
   1.515 -      int idx = index[i];
   1.516 +      int idx = _iim[i];
   1.517        if (idx >= 0) idx = 0;
   1.518        return State(idx);
   1.519      }
   1.520 @@ -552,11 +554,11 @@
   1.521        int next;
   1.522      };
   1.523  
   1.524 -    ItemIntMap& index;
   1.525 -    std::vector<int> first;
   1.526 -    std::vector<BucketItem> data;
   1.527 -    int free, num;
   1.528 -    mutable int minimal;
   1.529 +    ItemIntMap& _iim;
   1.530 +    std::vector<int> _first;
   1.531 +    std::vector<BucketItem> _data;
   1.532 +    int _free, _num;
   1.533 +    mutable int _minimum;
   1.534  
   1.535    }; // class SimpleBucketHeap
   1.536