88 /// The constructor. |
88 /// The constructor. |
89 /// \param _iim should be given to the constructor, since it is used |
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 |
90 /// internally to handle the cross references. The value of the map |
91 /// should be PRE_HEAP (-1) for each element. |
91 /// should be PRE_HEAP (-1) for each element. |
92 explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {} |
92 explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {} |
93 |
93 |
94 /// \brief The constructor. |
94 /// \brief The constructor. |
95 /// |
95 /// |
96 /// The constructor. |
96 /// The constructor. |
97 /// \param _iim should be given to the constructor, since it is used |
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 |
98 /// internally to handle the cross references. The value of the map |
99 /// should be PRE_HEAP (-1) for each element. |
99 /// should be PRE_HEAP (-1) for each element. |
100 /// |
100 /// |
101 /// \param _comp The comparator function object. |
101 /// \param _comp The comparator function object. |
102 BinHeap(ItemIntMap &_iim, const Compare &_comp) |
102 BinHeap(ItemIntMap &_iim, const Compare &_comp) |
103 : iim(_iim), comp(_comp) {} |
103 : iim(_iim), comp(_comp) {} |
104 |
104 |
105 |
105 |
106 /// The number of items stored in the heap. |
106 /// The number of items stored in the heap. |
107 /// |
107 /// |
108 /// \brief Returns the number of items stored in the heap. |
108 /// \brief Returns the number of items stored in the heap. |
109 int size() const { return data.size(); } |
109 int size() const { return data.size(); } |
110 |
110 |
111 /// \brief Checks if the heap stores no items. |
111 /// \brief Checks if the heap stores no items. |
112 /// |
112 /// |
113 /// Returns \c true if and only if the heap stores no items. |
113 /// Returns \c true if and only if the heap stores no items. |
114 bool empty() const { return data.empty(); } |
114 bool empty() const { return data.empty(); } |
115 |
115 |
116 /// \brief Make empty this heap. |
116 /// \brief Make empty this heap. |
117 /// |
117 /// |
118 /// Make empty this heap. It does not change the cross reference map. |
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 |
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 |
120 /// the heap and after that you should set the cross reference map for |
121 /// each item to \c PRE_HEAP. |
121 /// each item to \c PRE_HEAP. |
122 void clear() { |
122 void clear() { |
123 data.clear(); |
123 data.clear(); |
124 } |
124 } |
125 |
125 |
126 private: |
126 private: |
127 static int parent(int i) { return (i-1)/2; } |
127 static int parent(int i) { return (i-1)/2; } |
128 |
128 |
132 } |
132 } |
133 |
133 |
134 int bubble_up(int hole, Pair p) { |
134 int bubble_up(int hole, Pair p) { |
135 int par = parent(hole); |
135 int par = parent(hole); |
136 while( hole>0 && less(p,data[par]) ) { |
136 while( hole>0 && less(p,data[par]) ) { |
137 move(data[par],hole); |
137 move(data[par],hole); |
138 hole = par; |
138 hole = par; |
139 par = parent(hole); |
139 par = parent(hole); |
140 } |
140 } |
141 move(p, hole); |
141 move(p, hole); |
142 return hole; |
142 return hole; |
143 } |
143 } |
144 |
144 |
145 int bubble_down(int hole, Pair p, int length) { |
145 int bubble_down(int hole, Pair p, int length) { |
146 int child = second_child(hole); |
146 int child = second_child(hole); |
147 while(child < length) { |
147 while(child < length) { |
148 if( less(data[child-1], data[child]) ) { |
148 if( less(data[child-1], data[child]) ) { |
149 --child; |
149 --child; |
150 } |
150 } |
151 if( !less(data[child], p) ) |
151 if( !less(data[child], p) ) |
152 goto ok; |
152 goto ok; |
153 move(data[child], hole); |
153 move(data[child], hole); |
154 hole = child; |
154 hole = child; |
155 child = second_child(hole); |
155 child = second_child(hole); |
156 } |
156 } |
157 child--; |
157 child--; |
158 if( child<length && less(data[child], p) ) { |
158 if( child<length && less(data[child], p) ) { |
159 move(data[child], hole); |
159 move(data[child], hole); |
160 hole=child; |
160 hole=child; |
161 } |
161 } |
162 ok: |
162 ok: |
163 move(p, hole); |
163 move(p, hole); |
164 return hole; |
164 return hole; |
165 } |
165 } |
179 data.resize(n+1); |
179 data.resize(n+1); |
180 bubble_up(n, p); |
180 bubble_up(n, p); |
181 } |
181 } |
182 |
182 |
183 /// \brief Insert an item into the heap with the given heap. |
183 /// \brief Insert an item into the heap with the given heap. |
184 /// |
184 /// |
185 /// Adds \c i to the heap with priority \c p. |
185 /// Adds \c i to the heap with priority \c p. |
186 /// \param i The item to insert. |
186 /// \param i The item to insert. |
187 /// \param p The priority of the item. |
187 /// \param p The priority of the item. |
188 void push(const Item &i, const Prio &p) { push(Pair(i,p)); } |
188 void push(const Item &i, const Prio &p) { push(Pair(i,p)); } |
189 |
189 |
190 /// \brief Returns the item with minimum priority relative to \c Compare. |
190 /// \brief Returns the item with minimum priority relative to \c Compare. |
191 /// |
191 /// |
192 /// This method returns the item with minimum priority relative to \c |
192 /// This method returns the item with minimum priority relative to \c |
193 /// Compare. |
193 /// Compare. |
194 /// \pre The heap must be nonempty. |
194 /// \pre The heap must be nonempty. |
195 Item top() const { |
195 Item top() const { |
196 return data[0].first; |
196 return data[0].first; |
197 } |
197 } |
198 |
198 |
199 /// \brief Returns the minimum priority relative to \c Compare. |
199 /// \brief Returns the minimum priority relative to \c Compare. |
205 } |
205 } |
206 |
206 |
207 /// \brief Deletes the item with minimum priority relative to \c Compare. |
207 /// \brief Deletes the item with minimum priority relative to \c Compare. |
208 /// |
208 /// |
209 /// This method deletes the item with minimum priority relative to \c |
209 /// This method deletes the item with minimum priority relative to \c |
210 /// Compare from the heap. |
210 /// Compare from the heap. |
211 /// \pre The heap must be non-empty. |
211 /// \pre The heap must be non-empty. |
212 void pop() { |
212 void pop() { |
213 int n = data.size()-1; |
213 int n = data.size()-1; |
214 iim.set(data[0].first, POST_HEAP); |
214 iim.set(data[0].first, POST_HEAP); |
215 if (n > 0) { |
215 if (n > 0) { |
216 bubble_down(0, data[n], n); |
216 bubble_down(0, data[n], n); |
217 } |
217 } |
218 data.pop_back(); |
218 data.pop_back(); |
219 } |
219 } |
220 |
220 |
221 /// \brief Deletes \c i from the heap. |
221 /// \brief Deletes \c i from the heap. |
226 void erase(const Item &i) { |
226 void erase(const Item &i) { |
227 int h = iim[i]; |
227 int h = iim[i]; |
228 int n = data.size()-1; |
228 int n = data.size()-1; |
229 iim.set(data[h].first, POST_HEAP); |
229 iim.set(data[h].first, POST_HEAP); |
230 if( h < n ) { |
230 if( h < n ) { |
231 if ( bubble_up(h, data[n]) == h) { |
231 if ( bubble_up(h, data[n]) == h) { |
232 bubble_down(h, data[n], n); |
232 bubble_down(h, data[n], n); |
233 } |
233 } |
234 } |
234 } |
235 data.pop_back(); |
235 data.pop_back(); |
236 } |
236 } |
237 |
237 |
238 |
238 |
239 /// \brief Returns the priority of \c i. |
239 /// \brief Returns the priority of \c i. |
240 /// |
240 /// |
241 /// This function returns the priority of item \c i. |
241 /// This function returns the priority of item \c i. |
242 /// \pre \c i must be in the heap. |
242 /// \pre \c i must be in the heap. |
243 /// \param i The item. |
243 /// \param i The item. |
244 Prio operator[](const Item &i) const { |
244 Prio operator[](const Item &i) const { |
245 int idx = iim[i]; |
245 int idx = iim[i]; |
246 return data[idx].second; |
246 return data[idx].second; |
247 } |
247 } |
248 |
248 |
249 /// \brief \c i gets to the heap with priority \c p independently |
249 /// \brief \c i gets to the heap with priority \c p independently |
250 /// if \c i was already there. |
250 /// if \c i was already there. |
251 /// |
251 /// |
252 /// This method calls \ref push(\c i, \c p) if \c i is not stored |
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. |
253 /// in the heap and sets the priority of \c i to \c p otherwise. |
254 /// \param i The item. |
254 /// \param i The item. |
255 /// \param p The priority. |
255 /// \param p The priority. |
256 void set(const Item &i, const Prio &p) { |
256 void set(const Item &i, const Prio &p) { |
257 int idx = iim[i]; |
257 int idx = iim[i]; |
258 if( idx < 0 ) { |
258 if( idx < 0 ) { |
259 push(i,p); |
259 push(i,p); |
260 } |
260 } |
261 else if( comp(p, data[idx].second) ) { |
261 else if( comp(p, data[idx].second) ) { |
262 bubble_up(idx, Pair(i,p)); |
262 bubble_up(idx, Pair(i,p)); |
263 } |
263 } |
264 else { |
264 else { |
265 bubble_down(idx, Pair(i,p), data.size()); |
265 bubble_down(idx, Pair(i,p), data.size()); |
266 } |
266 } |
267 } |
267 } |
268 |
268 |
269 /// \brief Decreases the priority of \c i to \c p. |
269 /// \brief Decreases the priority of \c i to \c p. |
270 /// |
270 /// |
275 /// \param p The priority. |
275 /// \param p The priority. |
276 void decrease(const Item &i, const Prio &p) { |
276 void decrease(const Item &i, const Prio &p) { |
277 int idx = iim[i]; |
277 int idx = iim[i]; |
278 bubble_up(idx, Pair(i,p)); |
278 bubble_up(idx, Pair(i,p)); |
279 } |
279 } |
280 |
280 |
281 /// \brief Increases the priority of \c i to \c p. |
281 /// \brief Increases the priority of \c i to \c p. |
282 /// |
282 /// |
283 /// This method sets the priority of item \c i to \c p. |
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 |
284 /// \pre \c i must be stored in the heap with priority at most \c |
285 /// p relative to \c Compare. |
285 /// p relative to \c Compare. |
286 /// \param i The item. |
286 /// \param i The item. |
287 /// \param p The priority. |
287 /// \param p The priority. |
288 void increase(const Item &i, const Prio &p) { |
288 void increase(const Item &i, const Prio &p) { |
289 int idx = iim[i]; |
289 int idx = iim[i]; |
290 bubble_down(idx, Pair(i,p), data.size()); |
290 bubble_down(idx, Pair(i,p), data.size()); |
291 } |
291 } |
292 |
292 |
293 /// \brief Returns if \c item is in, has already been in, or has |
293 /// \brief Returns if \c item is in, has already been in, or has |
294 /// never been in the heap. |
294 /// never been in the heap. |
295 /// |
295 /// |
296 /// This method returns PRE_HEAP if \c item has never been in the |
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 |
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 |
298 /// otherwise. In the latter case it is possible that \c item will |
299 /// get back to the heap again. |
299 /// get back to the heap again. |
300 /// \param i The item. |
300 /// \param i The item. |
301 State state(const Item &i) const { |
301 State state(const Item &i) const { |
302 int s = iim[i]; |
302 int s = iim[i]; |
303 if( s>=0 ) |
303 if( s>=0 ) |
304 s=0; |
304 s=0; |
305 return State(s); |
305 return State(s); |
306 } |
306 } |
307 |
307 |
308 /// \brief Sets the state of the \c item in the heap. |
308 /// \brief Sets the state of the \c item in the heap. |
309 /// |
309 /// |
310 /// Sets the state of the \c item in the heap. It can be used to |
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 |
311 /// manually clear the heap when it is important to achive the |
312 /// better time complexity. |
312 /// better time complexity. |
313 /// \param i The item. |
313 /// \param i The item. |
314 /// \param st The state. It should not be \c IN_HEAP. |
314 /// \param st The state. It should not be \c IN_HEAP. |
315 void state(const Item& i, State st) { |
315 void state(const Item& i, State st) { |
316 switch (st) { |
316 switch (st) { |
317 case POST_HEAP: |
317 case POST_HEAP: |
318 case PRE_HEAP: |
318 case PRE_HEAP: |
319 if (state(i) == IN_HEAP) { |
319 if (state(i) == IN_HEAP) { |