37 ///is a data structure for storing items with specified values called \e |
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 |
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 |
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. |
40 ///one can change the priority of an item, add or erase an item, etc. |
41 /// |
41 /// |
42 ///\param Item Type of the items to be stored. |
|
43 ///\param Prio Type of the priority of the items. |
42 ///\param Prio Type of the priority of the items. |
44 ///\param ItemIntMap A read and writable Item int map, used internally |
43 ///\param ItemIntMap A read and writable Item int map, used internally |
45 ///to handle the cross references. |
44 ///to handle the cross references. |
46 ///\param Compare A class for the ordering of the priorities. The |
45 ///\param Compare A class for the ordering of the priorities. The |
47 ///default is \c std::less<Prio>. |
46 ///default is \c std::less<Prio>. |
48 /// |
47 /// |
49 ///\sa FibHeap |
48 ///\sa FibHeap |
50 ///\sa Dijkstra |
49 ///\sa Dijkstra |
51 template <typename Item, typename Prio, typename ItemIntMap, |
50 template <typename Prio, typename ItemIntMap, |
52 typename Compare = std::less<Prio> > |
51 typename Compare = std::less<Prio> > |
53 class BinHeap { |
52 class BinHeap { |
54 |
53 |
55 public: |
54 public: |
56 typedef Item ItemType; |
55 typedef typename ItemIntMap::Key ItemType; |
57 typedef Prio PrioType; |
56 typedef Prio PrioType; |
58 typedef std::pair<ItemType,PrioType> PairType; |
57 typedef std::pair<ItemType,PrioType> PairType; |
59 typedef ItemIntMap ItemIntMapType; |
58 typedef ItemIntMap ItemIntMapType; |
60 typedef Compare PrioCompare; |
59 typedef Compare PrioCompare; |
61 |
60 |
159 /// \brief Insert an item into the heap with the given heap. |
158 /// \brief Insert an item into the heap with the given heap. |
160 /// |
159 /// |
161 /// Adds \c i to the heap with priority \c p. |
160 /// Adds \c i to the heap with priority \c p. |
162 /// \param i The item to insert. |
161 /// \param i The item to insert. |
163 /// \param p The priority of the item. |
162 /// \param p The priority of the item. |
164 void push(const Item &i, const Prio &p) { push(PairType(i,p)); } |
163 void push(const ItemType &i, const Prio &p) { push(PairType(i,p)); } |
165 |
164 |
166 /// \brief Returns the item with minimum priority relative to \c Compare. |
165 /// \brief Returns the item with minimum priority relative to \c Compare. |
167 /// |
166 /// |
168 /// This method returns the item with minimum priority relative to \c |
167 /// This method returns the item with minimum priority relative to \c |
169 /// Compare. |
168 /// Compare. |
170 /// \pre The heap must be nonempty. |
169 /// \pre The heap must be nonempty. |
171 Item top() const { |
170 ItemType top() const { |
172 return data[0].first; |
171 return data[0].first; |
173 } |
172 } |
174 |
173 |
175 /// \brief Returns the minimum priority relative to \c Compare. |
174 /// \brief Returns the minimum priority relative to \c Compare. |
176 /// |
175 /// |
192 /// \brief Deletes \c i from the heap. |
191 /// \brief Deletes \c i from the heap. |
193 /// |
192 /// |
194 /// This method deletes item \c i from the heap, if \c i was |
193 /// This method deletes item \c i from the heap, if \c i was |
195 /// already stored in the heap. |
194 /// already stored in the heap. |
196 /// \param i The item to erase. |
195 /// \param i The item to erase. |
197 void erase(const Item &i) { |
196 void erase(const ItemType &i) { |
198 rmidx(iim[i]); |
197 rmidx(iim[i]); |
199 } |
198 } |
200 |
199 |
201 |
200 |
202 /// \brief Returns the priority of \c i. |
201 /// \brief Returns the priority of \c i. |
203 /// |
202 /// |
204 /// This function returns the priority of item \c i. |
203 /// This function returns the priority of item \c i. |
205 /// \pre \c i must be in the heap. |
204 /// \pre \c i must be in the heap. |
206 /// \param i The item. |
205 /// \param i The item. |
207 Prio operator[](const Item &i) const { |
206 Prio operator[](const ItemType &i) const { |
208 int idx = iim[i]; |
207 int idx = iim[i]; |
209 return data[idx].second; |
208 return data[idx].second; |
210 } |
209 } |
211 |
210 |
212 /// \brief \c i gets to the heap with priority \c p independently |
211 /// \brief \c i gets to the heap with priority \c p independently |
214 /// |
213 /// |
215 /// This method calls \ref push(\c i, \c p) if \c i is not stored |
214 /// This method calls \ref push(\c i, \c p) if \c i is not stored |
216 /// in the heap and sets the priority of \c i to \c p otherwise. |
215 /// in the heap and sets the priority of \c i to \c p otherwise. |
217 /// \param i The item. |
216 /// \param i The item. |
218 /// \param p The priority. |
217 /// \param p The priority. |
219 void set(const Item &i, const Prio &p) { |
218 void set(const ItemType &i, const Prio &p) { |
220 int idx = iim[i]; |
219 int idx = iim[i]; |
221 if( idx < 0 ) { |
220 if( idx < 0 ) { |
222 push(i,p); |
221 push(i,p); |
223 } |
222 } |
224 else if( comp(p, data[idx].second) ) { |
223 else if( comp(p, data[idx].second) ) { |
234 /// This method decreases the priority of item \c i to \c p. |
233 /// This method decreases the priority of item \c i to \c p. |
235 /// \pre \c i must be stored in the heap with priority at least \c |
234 /// \pre \c i must be stored in the heap with priority at least \c |
236 /// p relative to \c Compare. |
235 /// p relative to \c Compare. |
237 /// \param i The item. |
236 /// \param i The item. |
238 /// \param p The priority. |
237 /// \param p The priority. |
239 void decrease(const Item &i, const Prio &p) { |
238 void decrease(const ItemType &i, const Prio &p) { |
240 int idx = iim[i]; |
239 int idx = iim[i]; |
241 bubble_up(idx, PairType(i,p)); |
240 bubble_up(idx, PairType(i,p)); |
242 } |
241 } |
243 |
242 |
244 /// \brief Increases the priority of \c i to \c p. |
243 /// \brief Increases the priority of \c i to \c p. |
246 /// This method sets the priority of item \c i to \c p. |
245 /// This method sets the priority of item \c i to \c p. |
247 /// \pre \c i must be stored in the heap with priority at most \c |
246 /// \pre \c i must be stored in the heap with priority at most \c |
248 /// p relative to \c Compare. |
247 /// p relative to \c Compare. |
249 /// \param i The item. |
248 /// \param i The item. |
250 /// \param p The priority. |
249 /// \param p The priority. |
251 void increase(const Item &i, const Prio &p) { |
250 void increase(const ItemType &i, const Prio &p) { |
252 int idx = iim[i]; |
251 int idx = iim[i]; |
253 bubble_down(idx, PairType(i,p), data.size()); |
252 bubble_down(idx, PairType(i,p), data.size()); |
254 } |
253 } |
255 |
254 |
256 /// \brief Returns if \c item is in, has already been in, or has |
255 /// \brief Returns if \c item is in, has already been in, or has |
259 /// This method returns PRE_HEAP if \c item has never been in the |
258 /// This method returns PRE_HEAP if \c item has never been in the |
260 /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP |
259 /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP |
261 /// otherwise. In the latter case it is possible that \c item will |
260 /// otherwise. In the latter case it is possible that \c item will |
262 /// get back to the heap again. |
261 /// get back to the heap again. |
263 /// \param i The item. |
262 /// \param i The item. |
264 state_enum state(const Item &i) const { |
263 state_enum state(const ItemType &i) const { |
265 int s = iim[i]; |
264 int s = iim[i]; |
266 if( s>=0 ) |
265 if( s>=0 ) |
267 s=0; |
266 s=0; |
268 return state_enum(s); |
267 return state_enum(s); |
269 } |
268 } |
273 /// Sets the state of the \c item in the heap. It can be used to |
272 /// Sets the state of the \c item in the heap. It can be used to |
274 /// manually clear the heap when it is important to achive the |
273 /// manually clear the heap when it is important to achive the |
275 /// better time complexity. |
274 /// better time complexity. |
276 /// \param i The item. |
275 /// \param i The item. |
277 /// \param st The state. It should not be \c IN_HEAP. |
276 /// \param st The state. It should not be \c IN_HEAP. |
278 void state(const Item& i, state_enum st) { |
277 void state(const ItemType& i, state_enum st) { |
279 switch (st) { |
278 switch (st) { |
280 case POST_HEAP: |
279 case POST_HEAP: |
281 case PRE_HEAP: |
280 case PRE_HEAP: |
282 if (state(i) == IN_HEAP) { |
281 if (state(i) == IN_HEAP) { |
283 erase(i); |
282 erase(i); |
290 } |
289 } |
291 |
290 |
292 }; // class BinHeap |
291 }; // class BinHeap |
293 |
292 |
294 |
293 |
295 template <typename K, typename V, typename M, typename C> |
294 template <typename V, typename M, typename C> |
296 int BinHeap<K,V,M,C>::bubble_up(int hole, PairType p) { |
295 int BinHeap<V,M,C>::bubble_up(int hole, PairType p) { |
297 int par = parent(hole); |
296 int par = parent(hole); |
298 while( hole>0 && less(p,data[par]) ) { |
297 while( hole>0 && less(p,data[par]) ) { |
299 move(data[par],hole); |
298 move(data[par],hole); |
300 hole = par; |
299 hole = par; |
301 par = parent(hole); |
300 par = parent(hole); |
302 } |
301 } |
303 move(p, hole); |
302 move(p, hole); |
304 return hole; |
303 return hole; |
305 } |
304 } |
306 |
305 |
307 template <typename K, typename V, typename M, typename C> |
306 template <typename V, typename M, typename C> |
308 int BinHeap<K,V,M,C>::bubble_down(int hole, PairType p, int length) { |
307 int BinHeap<V,M,C>::bubble_down(int hole, PairType p, int length) { |
309 int child = second_child(hole); |
308 int child = second_child(hole); |
310 while(child < length) { |
309 while(child < length) { |
311 if( less(data[child-1], data[child]) ) { |
310 if( less(data[child-1], data[child]) ) { |
312 --child; |
311 --child; |
313 } |
312 } |