Changes in lemon/bin_heap.h [758:28cfac049a6a:209:765619b7cbb2] in lemon
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/bin_heap.h
r758 r209 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-200 95 * Copyright (C) 2003-2008 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 20 20 #define LEMON_BIN_HEAP_H 21 21 22 ///\ingroup heaps22 ///\ingroup auxdat 23 23 ///\file 24 ///\brief Binary heap implementation.24 ///\brief Binary Heap implementation. 25 25 26 26 #include <vector> … … 30 30 namespace lemon { 31 31 32 /// \ingroup heaps32 ///\ingroup auxdat 33 33 /// 34 /// \brief Binary heap data structure.34 ///\brief A Binary Heap implementation. 35 35 /// 36 /// This class implements the \e binary \e heap data structure. 37 /// It fully conforms to the \ref concepts::Heap "heap concept". 36 ///This class implements the \e binary \e heap data structure. A \e heap 37 ///is a data structure for storing items with specified values called \e 38 ///priorities in such a way that finding the item with minimum priority is 39 ///efficient. \c Compare specifies the ordering of the priorities. In a heap 40 ///one can change the priority of an item, add or erase an item, etc. 38 41 /// 39 /// \tparam PR Type of the prioritiesof the items.40 /// \tparam IM A read-writable item map with \c int values, used41 /// internallyto handle the cross references.42 /// \tparam CMP A functor class for comparing the priorities.43 /// The default is \c std::less<PR>.44 #ifdef DOXYGEN 45 template <typename PR, typename IM, typename CMP>46 #else 47 template <typename PR, typename IM, typename CMP = std::less<PR> >48 #endif 42 ///\tparam _Prio Type of the priority of the items. 43 ///\tparam _ItemIntMap A read and writable Item int map, used internally 44 ///to handle the cross references. 45 ///\tparam _Compare A class for the ordering of the priorities. The 46 ///default is \c std::less<_Prio>. 47 /// 48 ///\sa FibHeap 49 ///\sa Dijkstra 50 template <typename _Prio, typename _ItemIntMap, 51 typename _Compare = std::less<_Prio> > 49 52 class BinHeap { 53 50 54 public: 51 52 /// Type of the item-int map. 53 typedef IM ItemIntMap; 54 /// Type of the priorities. 55 typedef PR Prio; 56 /// Type of the items stored in the heap. 55 ///\e 56 typedef _ItemIntMap ItemIntMap; 57 ///\e 58 typedef _Prio Prio; 59 ///\e 57 60 typedef typename ItemIntMap::Key Item; 58 /// Type of the item-priority pairs.61 ///\e 59 62 typedef std::pair<Item,Prio> Pair; 60 /// Functor type for comparing the priorities.61 typedef CMPCompare;62 63 /// \brief Type to represent the states of the items.64 /// 65 /// Each item has a state associated to it. It canbe "in heap",66 /// "pre -heap" or "post-heap". The latter two are indifferent from the63 ///\e 64 typedef _Compare Compare; 65 66 /// \brief Type to represent the items states. 67 /// 68 /// Each Item element have a state associated to it. It may be "in heap", 69 /// "pre heap" or "post heap". The latter two are indifferent from the 67 70 /// heap's point of view, but may be useful to the user. 68 71 /// 69 /// The item-int map must be initialized in such way that it assigns70 /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.72 /// The ItemIntMap \e should be initialized in such way that it maps 73 /// PRE_HEAP (-1) to any element to be put in the heap... 71 74 enum State { 72 IN_HEAP = 0, ///< = 0.73 PRE_HEAP = -1, ///< = -1.74 POST_HEAP = -2 ///< = -2.75 IN_HEAP = 0, 76 PRE_HEAP = -1, 77 POST_HEAP = -2 75 78 }; 76 79 77 80 private: 78 std::vector<Pair> _data;79 Compare _comp;80 ItemIntMap & _iim;81 std::vector<Pair> data; 82 Compare comp; 83 ItemIntMap &iim; 81 84 82 85 public: 83 84 /// \brief Constructor. 85 /// 86 /// Constructor. 87 /// \param map A map that assigns \c int values to the items. 88 /// It is used internally to handle the cross references. 89 /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item. 90 explicit BinHeap(ItemIntMap &map) : _iim(map) {} 91 92 /// \brief Constructor. 93 /// 94 /// Constructor. 95 /// \param map A map that assigns \c int values to the items. 96 /// It is used internally to handle the cross references. 97 /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item. 98 /// \param comp The function object used for comparing the priorities. 99 BinHeap(ItemIntMap &map, const Compare &comp) 100 : _iim(map), _comp(comp) {} 101 102 103 /// \brief The number of items stored in the heap. 104 /// 105 /// This function returns the number of items stored in the heap. 106 int size() const { return _data.size(); } 107 108 /// \brief Check if the heap is empty. 109 /// 110 /// This function returns \c true if the heap is empty. 111 bool empty() const { return _data.empty(); } 112 113 /// \brief Make the heap empty. 114 /// 115 /// This functon makes the heap empty. 116 /// It does not change the cross reference map. If you want to reuse 117 /// a heap that is not surely empty, you should first clear it and 118 /// then you should set the cross reference map to \c PRE_HEAP 119 /// for each item. 86 /// \brief The constructor. 87 /// 88 /// The constructor. 89 /// \param _iim should be given to the constructor, since it is used 90 /// internally to handle the cross references. The value of the map 91 /// should be PRE_HEAP (-1) for each element. 92 explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {} 93 94 /// \brief The constructor. 95 /// 96 /// The constructor. 97 /// \param _iim should be given to the constructor, since it is used 98 /// internally to handle the cross references. The value of the map 99 /// should be PRE_HEAP (-1) for each element. 100 /// 101 /// \param _comp The comparator function object. 102 BinHeap(ItemIntMap &_iim, const Compare &_comp) 103 : iim(_iim), comp(_comp) {} 104 105 106 /// The number of items stored in the heap. 107 /// 108 /// \brief Returns the number of items stored in the heap. 109 int size() const { return data.size(); } 110 111 /// \brief Checks if the heap stores no items. 112 /// 113 /// Returns \c true if and only if the heap stores no items. 114 bool empty() const { return data.empty(); } 115 116 /// \brief Make empty this heap. 117 /// 118 /// Make empty this heap. It does not change the cross reference map. 119 /// If you want to reuse what is not surely empty you should first clear 120 /// the heap and after that you should set the cross reference map for 121 /// each item to \c PRE_HEAP. 120 122 void clear() { 121 _data.clear();123 data.clear(); 122 124 } 123 125 … … 125 127 static int parent(int i) { return (i-1)/2; } 126 128 127 static int second Child(int i) { return 2*i+2; }129 static int second_child(int i) { return 2*i+2; } 128 130 bool less(const Pair &p1, const Pair &p2) const { 129 return _comp(p1.second, p2.second);130 } 131 132 int bubble Up(int hole, Pair p) {131 return comp(p1.second, p2.second); 132 } 133 134 int bubble_up(int hole, Pair p) { 133 135 int par = parent(hole); 134 while( hole>0 && less(p, _data[par]) ) {135 move( _data[par],hole);136 while( hole>0 && less(p,data[par]) ) { 137 move(data[par],hole); 136 138 hole = par; 137 139 par = parent(hole); … … 141 143 } 142 144 143 int bubble Down(int hole, Pair p, int length) {144 int child = second Child(hole);145 int bubble_down(int hole, Pair p, int length) { 146 int child = second_child(hole); 145 147 while(child < length) { 146 if( less( _data[child-1], _data[child]) ) {148 if( less(data[child-1], data[child]) ) { 147 149 --child; 148 150 } 149 if( !less( _data[child], p) )151 if( !less(data[child], p) ) 150 152 goto ok; 151 move( _data[child], hole);153 move(data[child], hole); 152 154 hole = child; 153 child = second Child(hole);155 child = second_child(hole); 154 156 } 155 157 child--; 156 if( child<length && less( _data[child], p) ) {157 move( _data[child], hole);158 if( child<length && less(data[child], p) ) { 159 move(data[child], hole); 158 160 hole=child; 159 161 } … … 164 166 165 167 void move(const Pair &p, int i) { 166 _data[i] = p;167 _iim.set(p.first, i);168 data[i] = p; 169 iim.set(p.first, i); 168 170 } 169 171 170 172 public: 171 172 173 /// \brief Insert a pair of item and priority into the heap. 173 174 /// 174 /// This function inserts \c p.first to the heap with priority 175 /// \c p.second. 175 /// Adds \c p.first to the heap with priority \c p.second. 176 176 /// \param p The pair to insert. 177 /// \pre \c p.first must not be stored in the heap.178 177 void push(const Pair &p) { 179 int n = _data.size(); 180 _data.resize(n+1); 181 bubbleUp(n, p); 182 } 183 184 /// \brief Insert an item into the heap with the given priority. 185 /// 186 /// This function inserts the given item into the heap with the 187 /// given priority. 178 int n = data.size(); 179 data.resize(n+1); 180 bubble_up(n, p); 181 } 182 183 /// \brief Insert an item into the heap with the given heap. 184 /// 185 /// Adds \c i to the heap with priority \c p. 188 186 /// \param i The item to insert. 189 187 /// \param p The priority of the item. 190 /// \pre \e i must not be stored in the heap.191 188 void push(const Item &i, const Prio &p) { push(Pair(i,p)); } 192 189 193 /// \brief Return the item having minimum priority. 194 /// 195 /// This function returns the item having minimum priority. 196 /// \pre The heap must be non-empty. 190 /// \brief Returns the item with minimum priority relative to \c Compare. 191 /// 192 /// This method returns the item with minimum priority relative to \c 193 /// Compare. 194 /// \pre The heap must be nonempty. 197 195 Item top() const { 198 return _data[0].first;199 } 200 201 /// \brief The minimum priority.202 /// 203 /// This function returns the minimum priority.204 /// \pre The heap must be non -empty.196 return data[0].first; 197 } 198 199 /// \brief Returns the minimum priority relative to \c Compare. 200 /// 201 /// It returns the minimum priority relative to \c Compare. 202 /// \pre The heap must be nonempty. 205 203 Prio prio() const { 206 return _data[0].second; 207 } 208 209 /// \brief Remove the item having minimum priority. 210 /// 211 /// This function removes the item having minimum priority. 204 return data[0].second; 205 } 206 207 /// \brief Deletes the item with minimum priority relative to \c Compare. 208 /// 209 /// This method deletes the item with minimum priority relative to \c 210 /// Compare from the heap. 212 211 /// \pre The heap must be non-empty. 213 212 void pop() { 214 int n = _data.size()-1;215 _iim.set(_data[0].first, POST_HEAP);213 int n = data.size()-1; 214 iim.set(data[0].first, POST_HEAP); 216 215 if (n > 0) { 217 bubbleDown(0, _data[n], n); 218 } 219 _data.pop_back(); 220 } 221 222 /// \brief Remove the given item from the heap. 223 /// 224 /// This function removes the given item from the heap if it is 225 /// already stored. 226 /// \param i The item to delete. 227 /// \pre \e i must be in the heap. 216 bubble_down(0, data[n], n); 217 } 218 data.pop_back(); 219 } 220 221 /// \brief Deletes \c i from the heap. 222 /// 223 /// This method deletes item \c i from the heap. 224 /// \param i The item to erase. 225 /// \pre The item should be in the heap. 228 226 void erase(const Item &i) { 229 int h = _iim[i];230 int n = _data.size()-1;231 _iim.set(_data[h].first, POST_HEAP);227 int h = iim[i]; 228 int n = data.size()-1; 229 iim.set(data[h].first, POST_HEAP); 232 230 if( h < n ) { 233 if ( bubble Up(h, _data[n]) == h) {234 bubble Down(h, _data[n], n);231 if ( bubble_up(h, data[n]) == h) { 232 bubble_down(h, data[n], n); 235 233 } 236 234 } 237 _data.pop_back(); 238 } 239 240 /// \brief The priority of the given item. 241 /// 242 /// This function returns the priority of the given item. 243 /// \param i The item. 244 /// \pre \e i must be in the heap. 235 data.pop_back(); 236 } 237 238 239 /// \brief Returns the priority of \c i. 240 /// 241 /// This function returns the priority of item \c i. 242 /// \pre \c i must be in the heap. 243 /// \param i The item. 245 244 Prio operator[](const Item &i) const { 246 int idx = _iim[i]; 247 return _data[idx].second; 248 } 249 250 /// \brief Set the priority of an item or insert it, if it is 251 /// not stored in the heap. 252 /// 253 /// This method sets the priority of the given item if it is 254 /// already stored in the heap. Otherwise it inserts the given 255 /// item into the heap with the given priority. 245 int idx = iim[i]; 246 return data[idx].second; 247 } 248 249 /// \brief \c i gets to the heap with priority \c p independently 250 /// if \c i was already there. 251 /// 252 /// This method calls \ref push(\c i, \c p) if \c i is not stored 253 /// in the heap and sets the priority of \c i to \c p otherwise. 256 254 /// \param i The item. 257 255 /// \param p The priority. 258 256 void set(const Item &i, const Prio &p) { 259 int idx = _iim[i];257 int idx = iim[i]; 260 258 if( idx < 0 ) { 261 259 push(i,p); 262 260 } 263 else if( _comp(p, _data[idx].second) ) {264 bubble Up(idx, Pair(i,p));261 else if( comp(p, data[idx].second) ) { 262 bubble_up(idx, Pair(i,p)); 265 263 } 266 264 else { 267 bubbleDown(idx, Pair(i,p), _data.size()); 268 } 269 } 270 271 /// \brief Decrease the priority of an item to the given value. 272 /// 273 /// This function decreases the priority of an item to the given value. 265 bubble_down(idx, Pair(i,p), data.size()); 266 } 267 } 268 269 /// \brief Decreases the priority of \c i to \c p. 270 /// 271 /// This method decreases the priority of item \c i to \c p. 272 /// \pre \c i must be stored in the heap with priority at least \c 273 /// p relative to \c Compare. 274 274 /// \param i The item. 275 275 /// \param p The priority. 276 /// \pre \e i must be stored in the heap with priority at least \e p.277 276 void decrease(const Item &i, const Prio &p) { 278 int idx = _iim[i]; 279 bubbleUp(idx, Pair(i,p)); 280 } 281 282 /// \brief Increase the priority of an item to the given value. 283 /// 284 /// This function increases the priority of an item to the given value. 277 int idx = iim[i]; 278 bubble_up(idx, Pair(i,p)); 279 } 280 281 /// \brief Increases the priority of \c i to \c p. 282 /// 283 /// This method sets the priority of item \c i to \c p. 284 /// \pre \c i must be stored in the heap with priority at most \c 285 /// p relative to \c Compare. 285 286 /// \param i The item. 286 287 /// \param p The priority. 287 /// \pre \e i must be stored in the heap with priority at most \e p.288 288 void increase(const Item &i, const Prio &p) { 289 int idx = _iim[i];290 bubble Down(idx, Pair(i,p), _data.size());291 } 292 293 /// \brief Return the state of an item.294 /// 295 /// This method returns \c PRE_HEAP if the given item has never296 /// been in the heap, \c IN_HEAP if it is in the heap at the moment,297 /// and \c POST_HEAP otherwise.298 /// In the latter case it is possible that the item will get back299 /// to the heap again.289 int idx = iim[i]; 290 bubble_down(idx, Pair(i,p), data.size()); 291 } 292 293 /// \brief Returns if \c item is in, has already been in, or has 294 /// never been in the heap. 295 /// 296 /// This method returns PRE_HEAP if \c item has never been in the 297 /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP 298 /// otherwise. In the latter case it is possible that \c item will 299 /// get back to the heap again. 300 300 /// \param i The item. 301 301 State state(const Item &i) const { 302 int s = _iim[i];302 int s = iim[i]; 303 303 if( s>=0 ) 304 304 s=0; … … 306 306 } 307 307 308 /// \brief Set the state of anitem in the heap.309 /// 310 /// This function sets the state of the given item in the heap.311 /// It can be used to manually clear the heap when it is important312 /// to achivebetter time complexity.308 /// \brief Sets the state of the \c item in the heap. 309 /// 310 /// Sets the state of the \c item in the heap. It can be used to 311 /// manually clear the heap when it is important to achive the 312 /// better time complexity. 313 313 /// \param i The item. 314 314 /// \param st The state. It should not be \c IN_HEAP. … … 320 320 erase(i); 321 321 } 322 _iim[i] = st;322 iim[i] = st; 323 323 break; 324 324 case IN_HEAP: … … 327 327 } 328 328 329 /// \brief Replace an item in the heap. 330 /// 331 /// This function replaces item \c i with item \c j. 332 /// Item \c i must be in the heap, while \c j must be out of the heap. 333 /// After calling this method, item \c i will be out of the 334 /// heap and \c j will be in the heap with the same prioriority 335 /// as item \c i had before. 329 /// \brief Replaces an item in the heap. 330 /// 331 /// The \c i item is replaced with \c j item. The \c i item should 332 /// be in the heap, while the \c j should be out of the heap. The 333 /// \c i item will out of the heap and \c j will be in the heap 334 /// with the same prioriority as prevoiusly the \c i item. 336 335 void replace(const Item& i, const Item& j) { 337 int idx = _iim[i];338 _iim.set(i, _iim[j]);339 _iim.set(j, idx);340 _data[idx].first = j;336 int idx = iim[i]; 337 iim.set(i, iim[j]); 338 iim.set(j, idx); 339 data[idx].first = j; 341 340 } 342 341
Note: See TracChangeset
for help on using the changeset viewer.