gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Unify member names in heaps (#299) The following renamings are made. Public members: - UnderFlowPriorityError -> PriorityUnderflowError ("underflow" is only one word) Private members: - bubble_up() -> bubbleUp() - bubble_down() -> bubbleDown() - second_child() -> secondChild() - makeroot() -> makeRoot() - relocate_last() -> relocateLast() - data -> _data - boxes -> _boxes
0 4 0
default
4 files changed with 97 insertions and 97 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BIN_HEAP_H
20 20
#define LEMON_BIN_HEAP_H
21 21

	
22 22
///\ingroup heaps
23 23
///\file
24 24
///\brief Binary heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <utility>
28 28
#include <functional>
29 29

	
30 30
namespace lemon {
31 31

	
32 32
  /// \ingroup heaps
33 33
  ///
34 34
  /// \brief Binary heap data structure.
35 35
  ///
36 36
  /// This class implements the \e binary \e heap data structure.
37 37
  /// It fully conforms to the \ref concepts::Heap "heap concept".
38 38
  ///
39 39
  /// \tparam PR Type of the priorities of the items.
40 40
  /// \tparam IM A read-writable item map with \c int values, used
41 41
  /// internally to handle the cross references.
42 42
  /// \tparam CMP A functor class for comparing the priorities.
43 43
  /// The default is \c std::less<PR>.
44 44
#ifdef DOXYGEN
45 45
  template <typename PR, typename IM, typename CMP>
46 46
#else
47 47
  template <typename PR, typename IM, typename CMP = std::less<PR> >
48 48
#endif
49 49
  class BinHeap {
50 50
  public:
51 51

	
52 52
    /// Type of the item-int map.
53 53
    typedef IM ItemIntMap;
54 54
    /// Type of the priorities.
55 55
    typedef PR Prio;
56 56
    /// Type of the items stored in the heap.
57 57
    typedef typename ItemIntMap::Key Item;
58 58
    /// Type of the item-priority pairs.
59 59
    typedef std::pair<Item,Prio> Pair;
60 60
    /// Functor type for comparing the priorities.
61 61
    typedef CMP Compare;
62 62

	
63 63
    /// \brief Type to represent the states of the items.
64 64
    ///
65 65
    /// Each item has a state associated to it. It can be "in heap",
66 66
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
67 67
    /// heap's point of view, but may be useful to the user.
68 68
    ///
69 69
    /// The item-int map must be initialized in such way that it assigns
70 70
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
71 71
    enum State {
72 72
      IN_HEAP = 0,    ///< = 0.
73 73
      PRE_HEAP = -1,  ///< = -1.
74 74
      POST_HEAP = -2  ///< = -2.
75 75
    };
76 76

	
77 77
  private:
78 78
    std::vector<Pair> _data;
79 79
    Compare _comp;
80 80
    ItemIntMap &_iim;
81 81

	
82 82
  public:
83 83

	
84 84
    /// \brief Constructor.
85 85
    ///
86 86
    /// Constructor.
87 87
    /// \param map A map that assigns \c int values to the items.
88 88
    /// It is used internally to handle the cross references.
89 89
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
90 90
    explicit BinHeap(ItemIntMap &map) : _iim(map) {}
91 91

	
92 92
    /// \brief Constructor.
93 93
    ///
94 94
    /// Constructor.
95 95
    /// \param map A map that assigns \c int values to the items.
96 96
    /// It is used internally to handle the cross references.
97 97
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
98 98
    /// \param comp The function object used for comparing the priorities.
99 99
    BinHeap(ItemIntMap &map, const Compare &comp)
100 100
      : _iim(map), _comp(comp) {}
101 101

	
102 102

	
103 103
    /// \brief The number of items stored in the heap.
104 104
    ///
105 105
    /// This function returns the number of items stored in the heap.
106 106
    int size() const { return _data.size(); }
107 107

	
108 108
    /// \brief Check if the heap is empty.
109 109
    ///
110 110
    /// This function returns \c true if the heap is empty.
111 111
    bool empty() const { return _data.empty(); }
112 112

	
113 113
    /// \brief Make the heap empty.
114 114
    ///
115 115
    /// This functon makes the heap empty.
116 116
    /// It does not change the cross reference map. If you want to reuse
117 117
    /// a heap that is not surely empty, you should first clear it and
118 118
    /// then you should set the cross reference map to \c PRE_HEAP
119 119
    /// for each item.
120 120
    void clear() {
121 121
      _data.clear();
122 122
    }
123 123

	
124 124
  private:
125 125
    static int parent(int i) { return (i-1)/2; }
126 126

	
127
    static int second_child(int i) { return 2*i+2; }
127
    static int secondChild(int i) { return 2*i+2; }
128 128
    bool less(const Pair &p1, const Pair &p2) const {
129 129
      return _comp(p1.second, p2.second);
130 130
    }
131 131

	
132
    int bubble_up(int hole, Pair p) {
132
    int bubbleUp(int hole, Pair p) {
133 133
      int par = parent(hole);
134 134
      while( hole>0 && less(p,_data[par]) ) {
135 135
        move(_data[par],hole);
136 136
        hole = par;
137 137
        par = parent(hole);
138 138
      }
139 139
      move(p, hole);
140 140
      return hole;
141 141
    }
142 142

	
143
    int bubble_down(int hole, Pair p, int length) {
144
      int child = second_child(hole);
143
    int bubbleDown(int hole, Pair p, int length) {
144
      int child = secondChild(hole);
145 145
      while(child < length) {
146 146
        if( less(_data[child-1], _data[child]) ) {
147 147
          --child;
148 148
        }
149 149
        if( !less(_data[child], p) )
150 150
          goto ok;
151 151
        move(_data[child], hole);
152 152
        hole = child;
153
        child = second_child(hole);
153
        child = secondChild(hole);
154 154
      }
155 155
      child--;
156 156
      if( child<length && less(_data[child], p) ) {
157 157
        move(_data[child], hole);
158 158
        hole=child;
159 159
      }
160 160
    ok:
161 161
      move(p, hole);
162 162
      return hole;
163 163
    }
164 164

	
165 165
    void move(const Pair &p, int i) {
166 166
      _data[i] = p;
167 167
      _iim.set(p.first, i);
168 168
    }
169 169

	
170 170
  public:
171 171

	
172 172
    /// \brief Insert a pair of item and priority into the heap.
173 173
    ///
174 174
    /// This function inserts \c p.first to the heap with priority
175 175
    /// \c p.second.
176 176
    /// \param p The pair to insert.
177 177
    /// \pre \c p.first must not be stored in the heap.
178 178
    void push(const Pair &p) {
179 179
      int n = _data.size();
180 180
      _data.resize(n+1);
181
      bubble_up(n, p);
181
      bubbleUp(n, p);
182 182
    }
183 183

	
184 184
    /// \brief Insert an item into the heap with the given priority.
185 185
    ///
186 186
    /// This function inserts the given item into the heap with the
187 187
    /// given priority.
188 188
    /// \param i The item to insert.
189 189
    /// \param p The priority of the item.
190 190
    /// \pre \e i must not be stored in the heap.
191 191
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
192 192

	
193 193
    /// \brief Return the item having minimum priority.
194 194
    ///
195 195
    /// This function returns the item having minimum priority.
196 196
    /// \pre The heap must be non-empty.
197 197
    Item top() const {
198 198
      return _data[0].first;
199 199
    }
200 200

	
201 201
    /// \brief The minimum priority.
202 202
    ///
203 203
    /// This function returns the minimum priority.
204 204
    /// \pre The heap must be non-empty.
205 205
    Prio prio() const {
206 206
      return _data[0].second;
207 207
    }
208 208

	
209 209
    /// \brief Remove the item having minimum priority.
210 210
    ///
211 211
    /// This function removes the item having minimum priority.
212 212
    /// \pre The heap must be non-empty.
213 213
    void pop() {
214 214
      int n = _data.size()-1;
215 215
      _iim.set(_data[0].first, POST_HEAP);
216 216
      if (n > 0) {
217
        bubble_down(0, _data[n], n);
217
        bubbleDown(0, _data[n], n);
218 218
      }
219 219
      _data.pop_back();
220 220
    }
221 221

	
222 222
    /// \brief Remove the given item from the heap.
223 223
    ///
224 224
    /// This function removes the given item from the heap if it is
225 225
    /// already stored.
226 226
    /// \param i The item to delete.
227 227
    /// \pre \e i must be in the heap.
228 228
    void erase(const Item &i) {
229 229
      int h = _iim[i];
230 230
      int n = _data.size()-1;
231 231
      _iim.set(_data[h].first, POST_HEAP);
232 232
      if( h < n ) {
233
        if ( bubble_up(h, _data[n]) == h) {
234
          bubble_down(h, _data[n], n);
233
        if ( bubbleUp(h, _data[n]) == h) {
234
          bubbleDown(h, _data[n], n);
235 235
        }
236 236
      }
237 237
      _data.pop_back();
238 238
    }
239 239

	
240 240
    /// \brief The priority of the given item.
241 241
    ///
242 242
    /// This function returns the priority of the given item.
243 243
    /// \param i The item.
244 244
    /// \pre \e i must be in the heap.
245 245
    Prio operator[](const Item &i) const {
246 246
      int idx = _iim[i];
247 247
      return _data[idx].second;
248 248
    }
249 249

	
250 250
    /// \brief Set the priority of an item or insert it, if it is
251 251
    /// not stored in the heap.
252 252
    ///
253 253
    /// This method sets the priority of the given item if it is
254 254
    /// already stored in the heap. Otherwise it inserts the given
255 255
    /// item into the heap with the given priority.
256 256
    /// \param i The item.
257 257
    /// \param p The priority.
258 258
    void set(const Item &i, const Prio &p) {
259 259
      int idx = _iim[i];
260 260
      if( idx < 0 ) {
261 261
        push(i,p);
262 262
      }
263 263
      else if( _comp(p, _data[idx].second) ) {
264
        bubble_up(idx, Pair(i,p));
264
        bubbleUp(idx, Pair(i,p));
265 265
      }
266 266
      else {
267
        bubble_down(idx, Pair(i,p), _data.size());
267
        bubbleDown(idx, Pair(i,p), _data.size());
268 268
      }
269 269
    }
270 270

	
271 271
    /// \brief Decrease the priority of an item to the given value.
272 272
    ///
273 273
    /// This function decreases the priority of an item to the given value.
274 274
    /// \param i The item.
275 275
    /// \param p The priority.
276 276
    /// \pre \e i must be stored in the heap with priority at least \e p.
277 277
    void decrease(const Item &i, const Prio &p) {
278 278
      int idx = _iim[i];
279
      bubble_up(idx, Pair(i,p));
279
      bubbleUp(idx, Pair(i,p));
280 280
    }
281 281

	
282 282
    /// \brief Increase the priority of an item to the given value.
283 283
    ///
284 284
    /// This function increases the priority of an item to the given value.
285 285
    /// \param i The item.
286 286
    /// \param p The priority.
287 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 289
      int idx = _iim[i];
290
      bubble_down(idx, Pair(i,p), _data.size());
290
      bubbleDown(idx, Pair(i,p), _data.size());
291 291
    }
292 292

	
293 293
    /// \brief Return the state of an item.
294 294
    ///
295 295
    /// This method returns \c PRE_HEAP if the given item has never
296 296
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
297 297
    /// and \c POST_HEAP otherwise.
298 298
    /// In the latter case it is possible that the item will get back
299 299
    /// to the heap again.
300 300
    /// \param i The item.
301 301
    State state(const Item &i) const {
302 302
      int s = _iim[i];
303 303
      if( s>=0 )
304 304
        s=0;
305 305
      return State(s);
306 306
    }
307 307

	
308 308
    /// \brief Set the state of an item in the heap.
309 309
    ///
310 310
    /// This function sets the state of the given item in the heap.
311 311
    /// It can be used to manually clear the heap when it is important
312 312
    /// to achive better time complexity.
313 313
    /// \param i The item.
314 314
    /// \param st The state. It should not be \c IN_HEAP.
315 315
    void state(const Item& i, State st) {
316 316
      switch (st) {
317 317
      case POST_HEAP:
318 318
      case PRE_HEAP:
319 319
        if (state(i) == IN_HEAP) {
320 320
          erase(i);
321 321
        }
322 322
        _iim[i] = st;
323 323
        break;
324 324
      case IN_HEAP:
325 325
        break;
326 326
      }
327 327
    }
328 328

	
329 329
    /// \brief Replace an item in the heap.
330 330
    ///
331 331
    /// This function replaces item \c i with item \c j.
332 332
    /// Item \c i must be in the heap, while \c j must be out of the heap.
333 333
    /// After calling this method, item \c i will be out of the
334 334
    /// heap and \c j will be in the heap with the same prioriority
335 335
    /// as item \c i had before.
336 336
    void replace(const Item& i, const Item& j) {
337 337
      int idx = _iim[i];
338 338
      _iim.set(i, _iim[j]);
339 339
      _iim.set(j, idx);
340 340
      _data[idx].first = j;
341 341
    }
342 342

	
343 343
  }; // class BinHeap
344 344

	
345 345
} // namespace lemon
346 346

	
347 347
#endif // LEMON_BIN_HEAP_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BUCKET_HEAP_H
20 20
#define LEMON_BUCKET_HEAP_H
21 21

	
22 22
///\ingroup heaps
23 23
///\file
24 24
///\brief Bucket heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <utility>
28 28
#include <functional>
29 29

	
30 30
namespace lemon {
31 31

	
32 32
  namespace _bucket_heap_bits {
33 33

	
34 34
    template <bool MIN>
35 35
    struct DirectionTraits {
36 36
      static bool less(int left, int right) {
37 37
        return left < right;
38 38
      }
39 39
      static void increase(int& value) {
40 40
        ++value;
41 41
      }
42 42
    };
43 43

	
44 44
    template <>
45 45
    struct DirectionTraits<false> {
46 46
      static bool less(int left, int right) {
47 47
        return left > right;
48 48
      }
49 49
      static void increase(int& value) {
50 50
        --value;
51 51
      }
52 52
    };
53 53

	
54 54
  }
55 55

	
56 56
  /// \ingroup heaps
57 57
  ///
58 58
  /// \brief Bucket heap data structure.
59 59
  ///
60 60
  /// This class implements the \e bucket \e heap data structure.
61 61
  /// It practically conforms to the \ref concepts::Heap "heap concept",
62 62
  /// but it has some limitations.
63 63
  ///
64 64
  /// The bucket heap is a very simple structure. It can store only
65 65
  /// \c int priorities and it maintains a list of items for each priority
66 66
  /// in the range <tt>[0..C)</tt>. So it should only be used when the
67 67
  /// priorities are small. It is not intended to use as a Dijkstra heap.
68 68
  ///
69 69
  /// \tparam IM A read-writable item map with \c int values, used
70 70
  /// internally to handle the cross references.
71 71
  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
72 72
  /// The default is \e min-heap. If this parameter is set to \c false,
73 73
  /// then the comparison is reversed, so the top(), prio() and pop()
74 74
  /// functions deal with the item having maximum priority instead of the
75 75
  /// minimum.
76 76
  ///
77 77
  /// \sa SimpleBucketHeap
78 78
  template <typename IM, bool MIN = true>
79 79
  class BucketHeap {
80 80

	
81 81
  public:
82 82

	
83 83
    /// Type of the item-int map.
84 84
    typedef IM ItemIntMap;
85 85
    /// Type of the priorities.
86 86
    typedef int Prio;
87 87
    /// Type of the items stored in the heap.
88 88
    typedef typename ItemIntMap::Key Item;
89 89
    /// Type of the item-priority pairs.
90 90
    typedef std::pair<Item,Prio> Pair;
91 91

	
92 92
  private:
93 93

	
94 94
    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
95 95

	
96 96
  public:
97 97

	
98 98
    /// \brief Type to represent the states of the items.
99 99
    ///
100 100
    /// Each item has a state associated to it. It can be "in heap",
101 101
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
102 102
    /// heap's point of view, but may be useful to the user.
103 103
    ///
104 104
    /// The item-int map must be initialized in such way that it assigns
105 105
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
106 106
    enum State {
107 107
      IN_HEAP = 0,    ///< = 0.
108 108
      PRE_HEAP = -1,  ///< = -1.
109 109
      POST_HEAP = -2  ///< = -2.
110 110
    };
111 111

	
112 112
  public:
113 113

	
114 114
    /// \brief Constructor.
115 115
    ///
116 116
    /// Constructor.
117 117
    /// \param map A map that assigns \c int values to the items.
118 118
    /// It is used internally to handle the cross references.
119 119
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
120 120
    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
121 121

	
122 122
    /// \brief The number of items stored in the heap.
123 123
    ///
124 124
    /// This function returns the number of items stored in the heap.
125 125
    int size() const { return _data.size(); }
126 126

	
127 127
    /// \brief Check if the heap is empty.
128 128
    ///
129 129
    /// This function returns \c true if the heap is empty.
130 130
    bool empty() const { return _data.empty(); }
131 131

	
132 132
    /// \brief Make the heap empty.
133 133
    ///
134 134
    /// This functon makes the heap empty.
135 135
    /// It does not change the cross reference map. If you want to reuse
136 136
    /// a heap that is not surely empty, you should first clear it and
137 137
    /// then you should set the cross reference map to \c PRE_HEAP
138 138
    /// for each item.
139 139
    void clear() {
140 140
      _data.clear(); _first.clear(); _minimum = 0;
141 141
    }
142 142

	
143 143
  private:
144 144

	
145
    void relocate_last(int idx) {
145
    void relocateLast(int idx) {
146 146
      if (idx + 1 < int(_data.size())) {
147 147
        _data[idx] = _data.back();
148 148
        if (_data[idx].prev != -1) {
149 149
          _data[_data[idx].prev].next = idx;
150 150
        } else {
151 151
          _first[_data[idx].value] = idx;
152 152
        }
153 153
        if (_data[idx].next != -1) {
154 154
          _data[_data[idx].next].prev = idx;
155 155
        }
156 156
        _iim[_data[idx].item] = idx;
157 157
      }
158 158
      _data.pop_back();
159 159
    }
160 160

	
161 161
    void unlace(int idx) {
162 162
      if (_data[idx].prev != -1) {
163 163
        _data[_data[idx].prev].next = _data[idx].next;
164 164
      } else {
165 165
        _first[_data[idx].value] = _data[idx].next;
166 166
      }
167 167
      if (_data[idx].next != -1) {
168 168
        _data[_data[idx].next].prev = _data[idx].prev;
169 169
      }
170 170
    }
171 171

	
172 172
    void lace(int idx) {
173 173
      if (int(_first.size()) <= _data[idx].value) {
174 174
        _first.resize(_data[idx].value + 1, -1);
175 175
      }
176 176
      _data[idx].next = _first[_data[idx].value];
177 177
      if (_data[idx].next != -1) {
178 178
        _data[_data[idx].next].prev = idx;
179 179
      }
180 180
      _first[_data[idx].value] = idx;
181 181
      _data[idx].prev = -1;
182 182
    }
183 183

	
184 184
  public:
185 185

	
186 186
    /// \brief Insert a pair of item and priority into the heap.
187 187
    ///
188 188
    /// This function inserts \c p.first to the heap with priority
189 189
    /// \c p.second.
190 190
    /// \param p The pair to insert.
191 191
    /// \pre \c p.first must not be stored in the heap.
192 192
    void push(const Pair& p) {
193 193
      push(p.first, p.second);
194 194
    }
195 195

	
196 196
    /// \brief Insert an item into the heap with the given priority.
197 197
    ///
198 198
    /// This function inserts the given item into the heap with the
199 199
    /// given priority.
200 200
    /// \param i The item to insert.
201 201
    /// \param p The priority of the item.
202 202
    /// \pre \e i must not be stored in the heap.
203 203
    void push(const Item &i, const Prio &p) {
204 204
      int idx = _data.size();
205 205
      _iim[i] = idx;
206 206
      _data.push_back(BucketItem(i, p));
207 207
      lace(idx);
208 208
      if (Direction::less(p, _minimum)) {
209 209
        _minimum = p;
210 210
      }
211 211
    }
212 212

	
213 213
    /// \brief Return the item having minimum priority.
214 214
    ///
215 215
    /// This function returns the item having minimum priority.
216 216
    /// \pre The heap must be non-empty.
217 217
    Item top() const {
218 218
      while (_first[_minimum] == -1) {
219 219
        Direction::increase(_minimum);
220 220
      }
221 221
      return _data[_first[_minimum]].item;
222 222
    }
223 223

	
224 224
    /// \brief The minimum priority.
225 225
    ///
226 226
    /// This function returns the minimum priority.
227 227
    /// \pre The heap must be non-empty.
228 228
    Prio prio() const {
229 229
      while (_first[_minimum] == -1) {
230 230
        Direction::increase(_minimum);
231 231
      }
232 232
      return _minimum;
233 233
    }
234 234

	
235 235
    /// \brief Remove the item having minimum priority.
236 236
    ///
237 237
    /// This function removes the item having minimum priority.
238 238
    /// \pre The heap must be non-empty.
239 239
    void pop() {
240 240
      while (_first[_minimum] == -1) {
241 241
        Direction::increase(_minimum);
242 242
      }
243 243
      int idx = _first[_minimum];
244 244
      _iim[_data[idx].item] = -2;
245 245
      unlace(idx);
246
      relocate_last(idx);
246
      relocateLast(idx);
247 247
    }
248 248

	
249 249
    /// \brief Remove the given item from the heap.
250 250
    ///
251 251
    /// This function removes the given item from the heap if it is
252 252
    /// already stored.
253 253
    /// \param i The item to delete.
254 254
    /// \pre \e i must be in the heap.
255 255
    void erase(const Item &i) {
256 256
      int idx = _iim[i];
257 257
      _iim[_data[idx].item] = -2;
258 258
      unlace(idx);
259
      relocate_last(idx);
259
      relocateLast(idx);
260 260
    }
261 261

	
262 262
    /// \brief The priority of the given item.
263 263
    ///
264 264
    /// This function returns the priority of the given item.
265 265
    /// \param i The item.
266 266
    /// \pre \e i must be in the heap.
267 267
    Prio operator[](const Item &i) const {
268 268
      int idx = _iim[i];
269 269
      return _data[idx].value;
270 270
    }
271 271

	
272 272
    /// \brief Set the priority of an item or insert it, if it is
273 273
    /// not stored in the heap.
274 274
    ///
275 275
    /// This method sets the priority of the given item if it is
276 276
    /// already stored in the heap. Otherwise it inserts the given
277 277
    /// item into the heap with the given priority.
278 278
    /// \param i The item.
279 279
    /// \param p The priority.
280 280
    void set(const Item &i, const Prio &p) {
281 281
      int idx = _iim[i];
282 282
      if (idx < 0) {
283 283
        push(i, p);
284 284
      } else if (Direction::less(p, _data[idx].value)) {
285 285
        decrease(i, p);
286 286
      } else {
287 287
        increase(i, p);
288 288
      }
289 289
    }
290 290

	
291 291
    /// \brief Decrease the priority of an item to the given value.
292 292
    ///
293 293
    /// This function decreases the priority of an item to the given value.
294 294
    /// \param i The item.
295 295
    /// \param p The priority.
296 296
    /// \pre \e i must be stored in the heap with priority at least \e p.
297 297
    void decrease(const Item &i, const Prio &p) {
298 298
      int idx = _iim[i];
299 299
      unlace(idx);
300 300
      _data[idx].value = p;
301 301
      if (Direction::less(p, _minimum)) {
302 302
        _minimum = p;
303 303
      }
304 304
      lace(idx);
305 305
    }
306 306

	
307 307
    /// \brief Increase the priority of an item to the given value.
308 308
    ///
309 309
    /// This function increases the priority of an item to the given value.
310 310
    /// \param i The item.
311 311
    /// \param p The priority.
312 312
    /// \pre \e i must be stored in the heap with priority at most \e p.
313 313
    void increase(const Item &i, const Prio &p) {
314 314
      int idx = _iim[i];
315 315
      unlace(idx);
316 316
      _data[idx].value = p;
317 317
      lace(idx);
318 318
    }
319 319

	
320 320
    /// \brief Return the state of an item.
321 321
    ///
322 322
    /// This method returns \c PRE_HEAP if the given item has never
323 323
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
324 324
    /// and \c POST_HEAP otherwise.
325 325
    /// In the latter case it is possible that the item will get back
326 326
    /// to the heap again.
327 327
    /// \param i The item.
328 328
    State state(const Item &i) const {
329 329
      int idx = _iim[i];
330 330
      if (idx >= 0) idx = 0;
331 331
      return State(idx);
332 332
    }
333 333

	
334 334
    /// \brief Set the state of an item in the heap.
335 335
    ///
336 336
    /// This function sets the state of the given item in the heap.
337 337
    /// It can be used to manually clear the heap when it is important
338 338
    /// to achive better time complexity.
339 339
    /// \param i The item.
340 340
    /// \param st The state. It should not be \c IN_HEAP.
341 341
    void state(const Item& i, State st) {
342 342
      switch (st) {
343 343
      case POST_HEAP:
344 344
      case PRE_HEAP:
345 345
        if (state(i) == IN_HEAP) {
346 346
          erase(i);
347 347
        }
348 348
        _iim[i] = st;
349 349
        break;
350 350
      case IN_HEAP:
351 351
        break;
352 352
      }
353 353
    }
354 354

	
355 355
  private:
356 356

	
357 357
    struct BucketItem {
358 358
      BucketItem(const Item& _item, int _value)
359 359
        : item(_item), value(_value) {}
360 360

	
361 361
      Item item;
362 362
      int value;
363 363

	
364 364
      int prev, next;
365 365
    };
366 366

	
367 367
    ItemIntMap& _iim;
368 368
    std::vector<int> _first;
369 369
    std::vector<BucketItem> _data;
370 370
    mutable int _minimum;
371 371

	
372 372
  }; // class BucketHeap
373 373

	
374 374
  /// \ingroup heaps
375 375
  ///
376 376
  /// \brief Simplified bucket heap data structure.
377 377
  ///
378 378
  /// This class implements a simplified \e bucket \e heap data
379 379
  /// structure. It does not provide some functionality, but it is
380 380
  /// faster and simpler than BucketHeap. The main difference is
381 381
  /// that BucketHeap stores a doubly-linked list for each key while
382 382
  /// this class stores only simply-linked lists. It supports erasing
383 383
  /// only for the item having minimum priority and it does not support
384 384
  /// key increasing and decreasing.
385 385
  ///
386 386
  /// Note that this implementation does not conform to the
387 387
  /// \ref concepts::Heap "heap concept" due to the lack of some 
388 388
  /// functionality.
389 389
  ///
390 390
  /// \tparam IM A read-writable item map with \c int values, used
391 391
  /// internally to handle the cross references.
392 392
  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
393 393
  /// The default is \e min-heap. If this parameter is set to \c false,
394 394
  /// then the comparison is reversed, so the top(), prio() and pop()
395 395
  /// functions deal with the item having maximum priority instead of the
396 396
  /// minimum.
397 397
  ///
398 398
  /// \sa BucketHeap
399 399
  template <typename IM, bool MIN = true >
400 400
  class SimpleBucketHeap {
401 401

	
402 402
  public:
403 403

	
404 404
    /// Type of the item-int map.
405 405
    typedef IM ItemIntMap;
406 406
    /// Type of the priorities.
407 407
    typedef int Prio;
408 408
    /// Type of the items stored in the heap.
409 409
    typedef typename ItemIntMap::Key Item;
410 410
    /// Type of the item-priority pairs.
411 411
    typedef std::pair<Item,Prio> Pair;
412 412

	
413 413
  private:
414 414

	
415 415
    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
416 416

	
417 417
  public:
418 418

	
419 419
    /// \brief Type to represent the states of the items.
420 420
    ///
421 421
    /// Each item has a state associated to it. It can be "in heap",
422 422
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
423 423
    /// heap's point of view, but may be useful to the user.
424 424
    ///
425 425
    /// The item-int map must be initialized in such way that it assigns
426 426
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
427 427
    enum State {
428 428
      IN_HEAP = 0,    ///< = 0.
429 429
      PRE_HEAP = -1,  ///< = -1.
430 430
      POST_HEAP = -2  ///< = -2.
431 431
    };
432 432

	
433 433
  public:
434 434

	
435 435
    /// \brief Constructor.
436 436
    ///
437 437
    /// Constructor.
438 438
    /// \param map A map that assigns \c int values to the items.
439 439
    /// It is used internally to handle the cross references.
440 440
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
441 441
    explicit SimpleBucketHeap(ItemIntMap &map)
442 442
      : _iim(map), _free(-1), _num(0), _minimum(0) {}
443 443

	
444 444
    /// \brief The number of items stored in the heap.
445 445
    ///
446 446
    /// This function returns the number of items stored in the heap.
447 447
    int size() const { return _num; }
448 448

	
449 449
    /// \brief Check if the heap is empty.
450 450
    ///
451 451
    /// This function returns \c true if the heap is empty.
452 452
    bool empty() const { return _num == 0; }
453 453

	
454 454
    /// \brief Make the heap empty.
455 455
    ///
456 456
    /// This functon makes the heap empty.
457 457
    /// It does not change the cross reference map. If you want to reuse
458 458
    /// a heap that is not surely empty, you should first clear it and
459 459
    /// then you should set the cross reference map to \c PRE_HEAP
460 460
    /// for each item.
461 461
    void clear() {
462 462
      _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
463 463
    }
464 464

	
465 465
    /// \brief Insert a pair of item and priority into the heap.
466 466
    ///
467 467
    /// This function inserts \c p.first to the heap with priority
468 468
    /// \c p.second.
469 469
    /// \param p The pair to insert.
470 470
    /// \pre \c p.first must not be stored in the heap.
471 471
    void push(const Pair& p) {
472 472
      push(p.first, p.second);
473 473
    }
474 474

	
475 475
    /// \brief Insert an item into the heap with the given priority.
476 476
    ///
477 477
    /// This function inserts the given item into the heap with the
478 478
    /// given priority.
479 479
    /// \param i The item to insert.
480 480
    /// \param p The priority of the item.
481 481
    /// \pre \e i must not be stored in the heap.
482 482
    void push(const Item &i, const Prio &p) {
483 483
      int idx;
484 484
      if (_free == -1) {
485 485
        idx = _data.size();
486 486
        _data.push_back(BucketItem(i));
487 487
      } else {
488 488
        idx = _free;
489 489
        _free = _data[idx].next;
490 490
        _data[idx].item = i;
491 491
      }
492 492
      _iim[i] = idx;
493 493
      if (p >= int(_first.size())) _first.resize(p + 1, -1);
494 494
      _data[idx].next = _first[p];
495 495
      _first[p] = idx;
496 496
      if (Direction::less(p, _minimum)) {
497 497
        _minimum = p;
498 498
      }
499 499
      ++_num;
500 500
    }
501 501

	
502 502
    /// \brief Return the item having minimum priority.
503 503
    ///
504 504
    /// This function returns the item having minimum priority.
505 505
    /// \pre The heap must be non-empty.
506 506
    Item top() const {
507 507
      while (_first[_minimum] == -1) {
508 508
        Direction::increase(_minimum);
509 509
      }
510 510
      return _data[_first[_minimum]].item;
511 511
    }
512 512

	
513 513
    /// \brief The minimum priority.
514 514
    ///
515 515
    /// This function returns the minimum priority.
516 516
    /// \pre The heap must be non-empty.
517 517
    Prio prio() const {
518 518
      while (_first[_minimum] == -1) {
519 519
        Direction::increase(_minimum);
520 520
      }
521 521
      return _minimum;
522 522
    }
523 523

	
524 524
    /// \brief Remove the item having minimum priority.
525 525
    ///
526 526
    /// This function removes the item having minimum priority.
527 527
    /// \pre The heap must be non-empty.
528 528
    void pop() {
529 529
      while (_first[_minimum] == -1) {
530 530
        Direction::increase(_minimum);
531 531
      }
532 532
      int idx = _first[_minimum];
533 533
      _iim[_data[idx].item] = -2;
534 534
      _first[_minimum] = _data[idx].next;
535 535
      _data[idx].next = _free;
536 536
      _free = idx;
537 537
      --_num;
538 538
    }
539 539

	
540 540
    /// \brief The priority of the given item.
541 541
    ///
542 542
    /// This function returns the priority of the given item.
543 543
    /// \param i The item.
544 544
    /// \pre \e i must be in the heap.
545 545
    /// \warning This operator is not a constant time function because
546 546
    /// it scans the whole data structure to find the proper value.
547 547
    Prio operator[](const Item &i) const {
548 548
      for (int k = 0; k < int(_first.size()); ++k) {
549 549
        int idx = _first[k];
550 550
        while (idx != -1) {
551 551
          if (_data[idx].item == i) {
552 552
            return k;
553 553
          }
554 554
          idx = _data[idx].next;
555 555
        }
556 556
      }
557 557
      return -1;
558 558
    }
559 559

	
560 560
    /// \brief Return the state of an item.
561 561
    ///
562 562
    /// This method returns \c PRE_HEAP if the given item has never
563 563
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
564 564
    /// and \c POST_HEAP otherwise.
565 565
    /// In the latter case it is possible that the item will get back
566 566
    /// to the heap again.
567 567
    /// \param i The item.
568 568
    State state(const Item &i) const {
569 569
      int idx = _iim[i];
570 570
      if (idx >= 0) idx = 0;
571 571
      return State(idx);
572 572
    }
573 573

	
574 574
  private:
575 575

	
576 576
    struct BucketItem {
577 577
      BucketItem(const Item& _item)
578 578
        : item(_item) {}
579 579

	
580 580
      Item item;
581 581
      int next;
582 582
    };
583 583

	
584 584
    ItemIntMap& _iim;
585 585
    std::vector<int> _first;
586 586
    std::vector<BucketItem> _data;
587 587
    int _free, _num;
588 588
    mutable int _minimum;
589 589

	
590 590
  }; // class SimpleBucketHeap
591 591

	
592 592
}
593 593

	
594 594
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_FIB_HEAP_H
20 20
#define LEMON_FIB_HEAP_H
21 21

	
22 22
///\file
23 23
///\ingroup heaps
24 24
///\brief Fibonacci heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <utility>
28 28
#include <functional>
29 29
#include <lemon/math.h>
30 30

	
31 31
namespace lemon {
32 32

	
33 33
  /// \ingroup heaps
34 34
  ///
35 35
  /// \brief Fibonacci heap data structure.
36 36
  ///
37 37
  /// This class implements the \e Fibonacci \e heap data structure.
38 38
  /// It fully conforms to the \ref concepts::Heap "heap concept".
39 39
  ///
40 40
  /// The methods \ref increase() and \ref erase() are not efficient in a
41 41
  /// Fibonacci heap. In case of many calls of these operations, it is
42 42
  /// better to use other heap structure, e.g. \ref BinHeap "binary heap".
43 43
  ///
44 44
  /// \tparam PR Type of the priorities of the items.
45 45
  /// \tparam IM A read-writable item map with \c int values, used
46 46
  /// internally to handle the cross references.
47 47
  /// \tparam CMP A functor class for comparing the priorities.
48 48
  /// The default is \c std::less<PR>.
49 49
#ifdef DOXYGEN
50 50
  template <typename PR, typename IM, typename CMP>
51 51
#else
52 52
  template <typename PR, typename IM, typename CMP = std::less<PR> >
53 53
#endif
54 54
  class FibHeap {
55 55
  public:
56 56

	
57 57
    /// Type of the item-int map.
58 58
    typedef IM ItemIntMap;
59 59
    /// Type of the priorities.
60 60
    typedef PR Prio;
61 61
    /// Type of the items stored in the heap.
62 62
    typedef typename ItemIntMap::Key Item;
63 63
    /// Type of the item-priority pairs.
64 64
    typedef std::pair<Item,Prio> Pair;
65 65
    /// Functor type for comparing the priorities.
66 66
    typedef CMP Compare;
67 67

	
68 68
  private:
69 69
    class Store;
70 70

	
71 71
    std::vector<Store> _data;
72 72
    int _minimum;
73 73
    ItemIntMap &_iim;
74 74
    Compare _comp;
75 75
    int _num;
76 76

	
77 77
  public:
78 78

	
79 79
    /// \brief Type to represent the states of the items.
80 80
    ///
81 81
    /// Each item has a state associated to it. It can be "in heap",
82 82
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
83 83
    /// heap's point of view, but may be useful to the user.
84 84
    ///
85 85
    /// The item-int map must be initialized in such way that it assigns
86 86
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
87 87
    enum State {
88 88
      IN_HEAP = 0,    ///< = 0.
89 89
      PRE_HEAP = -1,  ///< = -1.
90 90
      POST_HEAP = -2  ///< = -2.
91 91
    };
92 92

	
93 93
    /// \brief Constructor.
94 94
    ///
95 95
    /// Constructor.
96 96
    /// \param map A map that assigns \c int values to the items.
97 97
    /// It is used internally to handle the cross references.
98 98
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
99 99
    explicit FibHeap(ItemIntMap &map)
100 100
      : _minimum(0), _iim(map), _num() {}
101 101

	
102 102
    /// \brief Constructor.
103 103
    ///
104 104
    /// Constructor.
105 105
    /// \param map A map that assigns \c int values to the items.
106 106
    /// It is used internally to handle the cross references.
107 107
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
108 108
    /// \param comp The function object used for comparing the priorities.
109 109
    FibHeap(ItemIntMap &map, const Compare &comp)
110 110
      : _minimum(0), _iim(map), _comp(comp), _num() {}
111 111

	
112 112
    /// \brief The number of items stored in the heap.
113 113
    ///
114 114
    /// This function returns the number of items stored in the heap.
115 115
    int size() const { return _num; }
116 116

	
117 117
    /// \brief Check if the heap is empty.
118 118
    ///
119 119
    /// This function returns \c true if the heap is empty.
120 120
    bool empty() const { return _num==0; }
121 121

	
122 122
    /// \brief Make the heap empty.
123 123
    ///
124 124
    /// This functon makes the heap empty.
125 125
    /// It does not change the cross reference map. If you want to reuse
126 126
    /// a heap that is not surely empty, you should first clear it and
127 127
    /// then you should set the cross reference map to \c PRE_HEAP
128 128
    /// for each item.
129 129
    void clear() {
130 130
      _data.clear(); _minimum = 0; _num = 0;
131 131
    }
132 132

	
133 133
    /// \brief Insert an item into the heap with the given priority.
134 134
    ///
135 135
    /// This function inserts the given item into the heap with the
136 136
    /// given priority.
137 137
    /// \param item The item to insert.
138 138
    /// \param prio The priority of the item.
139 139
    /// \pre \e item must not be stored in the heap.
140 140
    void push (const Item& item, const Prio& prio) {
141 141
      int i=_iim[item];
142 142
      if ( i < 0 ) {
143 143
        int s=_data.size();
144 144
        _iim.set( item, s );
145 145
        Store st;
146 146
        st.name=item;
147 147
        _data.push_back(st);
148 148
        i=s;
149 149
      } else {
150 150
        _data[i].parent=_data[i].child=-1;
151 151
        _data[i].degree=0;
152 152
        _data[i].in=true;
153 153
        _data[i].marked=false;
154 154
      }
155 155

	
156 156
      if ( _num ) {
157 157
        _data[_data[_minimum].right_neighbor].left_neighbor=i;
158 158
        _data[i].right_neighbor=_data[_minimum].right_neighbor;
159 159
        _data[_minimum].right_neighbor=i;
160 160
        _data[i].left_neighbor=_minimum;
161 161
        if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
162 162
      } else {
163 163
        _data[i].right_neighbor=_data[i].left_neighbor=i;
164 164
        _minimum=i;
165 165
      }
166 166
      _data[i].prio=prio;
167 167
      ++_num;
168 168
    }
169 169

	
170 170
    /// \brief Return the item having minimum priority.
171 171
    ///
172 172
    /// This function returns the item having minimum priority.
173 173
    /// \pre The heap must be non-empty.
174 174
    Item top() const { return _data[_minimum].name; }
175 175

	
176 176
    /// \brief The minimum priority.
177 177
    ///
178 178
    /// This function returns the minimum priority.
179 179
    /// \pre The heap must be non-empty.
180 180
    Prio prio() const { return _data[_minimum].prio; }
181 181

	
182 182
    /// \brief Remove the item having minimum priority.
183 183
    ///
184 184
    /// This function removes the item having minimum priority.
185 185
    /// \pre The heap must be non-empty.
186 186
    void pop() {
187 187
      /*The first case is that there are only one root.*/
188 188
      if ( _data[_minimum].left_neighbor==_minimum ) {
189 189
        _data[_minimum].in=false;
190 190
        if ( _data[_minimum].degree!=0 ) {
191
          makeroot(_data[_minimum].child);
191
          makeRoot(_data[_minimum].child);
192 192
          _minimum=_data[_minimum].child;
193 193
          balance();
194 194
        }
195 195
      } else {
196 196
        int right=_data[_minimum].right_neighbor;
197 197
        unlace(_minimum);
198 198
        _data[_minimum].in=false;
199 199
        if ( _data[_minimum].degree > 0 ) {
200 200
          int left=_data[_minimum].left_neighbor;
201 201
          int child=_data[_minimum].child;
202 202
          int last_child=_data[child].left_neighbor;
203 203

	
204
          makeroot(child);
204
          makeRoot(child);
205 205

	
206 206
          _data[left].right_neighbor=child;
207 207
          _data[child].left_neighbor=left;
208 208
          _data[right].left_neighbor=last_child;
209 209
          _data[last_child].right_neighbor=right;
210 210
        }
211 211
        _minimum=right;
212 212
        balance();
213 213
      } // the case where there are more roots
214 214
      --_num;
215 215
    }
216 216

	
217 217
    /// \brief Remove the given item from the heap.
218 218
    ///
219 219
    /// This function removes the given item from the heap if it is
220 220
    /// already stored.
221 221
    /// \param item The item to delete.
222 222
    /// \pre \e item must be in the heap.
223 223
    void erase (const Item& item) {
224 224
      int i=_iim[item];
225 225

	
226 226
      if ( i >= 0 && _data[i].in ) {
227 227
        if ( _data[i].parent!=-1 ) {
228 228
          int p=_data[i].parent;
229 229
          cut(i,p);
230 230
          cascade(p);
231 231
        }
232 232
        _minimum=i;     //As if its prio would be -infinity
233 233
        pop();
234 234
      }
235 235
    }
236 236

	
237 237
    /// \brief The priority of the given item.
238 238
    ///
239 239
    /// This function returns the priority of the given item.
240 240
    /// \param item The item.
241 241
    /// \pre \e item must be in the heap.
242 242
    Prio operator[](const Item& item) const {
243 243
      return _data[_iim[item]].prio;
244 244
    }
245 245

	
246 246
    /// \brief Set the priority of an item or insert it, if it is
247 247
    /// not stored in the heap.
248 248
    ///
249 249
    /// This method sets the priority of the given item if it is
250 250
    /// already stored in the heap. Otherwise it inserts the given
251 251
    /// item into the heap with the given priority.
252 252
    /// \param item The item.
253 253
    /// \param prio The priority.
254 254
    void set (const Item& item, const Prio& prio) {
255 255
      int i=_iim[item];
256 256
      if ( i >= 0 && _data[i].in ) {
257 257
        if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
258 258
        if ( _comp(_data[i].prio, prio) ) increase(item, prio);
259 259
      } else push(item, prio);
260 260
    }
261 261

	
262 262
    /// \brief Decrease the priority of an item to the given value.
263 263
    ///
264 264
    /// This function decreases the priority of an item to the given value.
265 265
    /// \param item The item.
266 266
    /// \param prio The priority.
267 267
    /// \pre \e item must be stored in the heap with priority at least \e prio.
268 268
    void decrease (const Item& item, const Prio& prio) {
269 269
      int i=_iim[item];
270 270
      _data[i].prio=prio;
271 271
      int p=_data[i].parent;
272 272

	
273 273
      if ( p!=-1 && _comp(prio, _data[p].prio) ) {
274 274
        cut(i,p);
275 275
        cascade(p);
276 276
      }
277 277
      if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
278 278
    }
279 279

	
280 280
    /// \brief Increase the priority of an item to the given value.
281 281
    ///
282 282
    /// This function increases the priority of an item to the given value.
283 283
    /// \param item The item.
284 284
    /// \param prio The priority.
285 285
    /// \pre \e item must be stored in the heap with priority at most \e prio.
286 286
    void increase (const Item& item, const Prio& prio) {
287 287
      erase(item);
288 288
      push(item, prio);
289 289
    }
290 290

	
291 291
    /// \brief Return the state of an item.
292 292
    ///
293 293
    /// This method returns \c PRE_HEAP if the given item has never
294 294
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
295 295
    /// and \c POST_HEAP otherwise.
296 296
    /// In the latter case it is possible that the item will get back
297 297
    /// to the heap again.
298 298
    /// \param item The item.
299 299
    State state(const Item &item) const {
300 300
      int i=_iim[item];
301 301
      if( i>=0 ) {
302 302
        if ( _data[i].in ) i=0;
303 303
        else i=-2;
304 304
      }
305 305
      return State(i);
306 306
    }
307 307

	
308 308
    /// \brief Set the state of an item in the heap.
309 309
    ///
310 310
    /// This function sets the state of the given item in the heap.
311 311
    /// It can be used to manually clear the heap when it is important
312 312
    /// to achive better time complexity.
313 313
    /// \param i The item.
314 314
    /// \param st The state. It should not be \c IN_HEAP.
315 315
    void state(const Item& i, State st) {
316 316
      switch (st) {
317 317
      case POST_HEAP:
318 318
      case PRE_HEAP:
319 319
        if (state(i) == IN_HEAP) {
320 320
          erase(i);
321 321
        }
322 322
        _iim[i] = st;
323 323
        break;
324 324
      case IN_HEAP:
325 325
        break;
326 326
      }
327 327
    }
328 328

	
329 329
  private:
330 330

	
331 331
    void balance() {
332 332

	
333 333
      int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
334 334

	
335 335
      std::vector<int> A(maxdeg,-1);
336 336

	
337 337
      /*
338 338
       *Recall that now minimum does not point to the minimum prio element.
339 339
       *We set minimum to this during balance().
340 340
       */
341 341
      int anchor=_data[_minimum].left_neighbor;
342 342
      int next=_minimum;
343 343
      bool end=false;
344 344

	
345 345
      do {
346 346
        int active=next;
347 347
        if ( anchor==active ) end=true;
348 348
        int d=_data[active].degree;
349 349
        next=_data[active].right_neighbor;
350 350

	
351 351
        while (A[d]!=-1) {
352 352
          if( _comp(_data[active].prio, _data[A[d]].prio) ) {
353 353
            fuse(active,A[d]);
354 354
          } else {
355 355
            fuse(A[d],active);
356 356
            active=A[d];
357 357
          }
358 358
          A[d]=-1;
359 359
          ++d;
360 360
        }
361 361
        A[d]=active;
362 362
      } while ( !end );
363 363

	
364 364

	
365 365
      while ( _data[_minimum].parent >=0 )
366 366
        _minimum=_data[_minimum].parent;
367 367
      int s=_minimum;
368 368
      int m=_minimum;
369 369
      do {
370 370
        if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
371 371
        s=_data[s].right_neighbor;
372 372
      } while ( s != m );
373 373
    }
374 374

	
375
    void makeroot(int c) {
375
    void makeRoot(int c) {
376 376
      int s=c;
377 377
      do {
378 378
        _data[s].parent=-1;
379 379
        s=_data[s].right_neighbor;
380 380
      } while ( s != c );
381 381
    }
382 382

	
383 383
    void cut(int a, int b) {
384 384
      /*
385 385
       *Replacing a from the children of b.
386 386
       */
387 387
      --_data[b].degree;
388 388

	
389 389
      if ( _data[b].degree !=0 ) {
390 390
        int child=_data[b].child;
391 391
        if ( child==a )
392 392
          _data[b].child=_data[child].right_neighbor;
393 393
        unlace(a);
394 394
      }
395 395

	
396 396

	
397 397
      /*Lacing a to the roots.*/
398 398
      int right=_data[_minimum].right_neighbor;
399 399
      _data[_minimum].right_neighbor=a;
400 400
      _data[a].left_neighbor=_minimum;
401 401
      _data[a].right_neighbor=right;
402 402
      _data[right].left_neighbor=a;
403 403

	
404 404
      _data[a].parent=-1;
405 405
      _data[a].marked=false;
406 406
    }
407 407

	
408 408
    void cascade(int a) {
409 409
      if ( _data[a].parent!=-1 ) {
410 410
        int p=_data[a].parent;
411 411

	
412 412
        if ( _data[a].marked==false ) _data[a].marked=true;
413 413
        else {
414 414
          cut(a,p);
415 415
          cascade(p);
416 416
        }
417 417
      }
418 418
    }
419 419

	
420 420
    void fuse(int a, int b) {
421 421
      unlace(b);
422 422

	
423 423
      /*Lacing b under a.*/
424 424
      _data[b].parent=a;
425 425

	
426 426
      if (_data[a].degree==0) {
427 427
        _data[b].left_neighbor=b;
428 428
        _data[b].right_neighbor=b;
429 429
        _data[a].child=b;
430 430
      } else {
431 431
        int child=_data[a].child;
432 432
        int last_child=_data[child].left_neighbor;
433 433
        _data[child].left_neighbor=b;
434 434
        _data[b].right_neighbor=child;
435 435
        _data[last_child].right_neighbor=b;
436 436
        _data[b].left_neighbor=last_child;
437 437
      }
438 438

	
439 439
      ++_data[a].degree;
440 440

	
441 441
      _data[b].marked=false;
442 442
    }
443 443

	
444 444
    /*
445 445
     *It is invoked only if a has siblings.
446 446
     */
447 447
    void unlace(int a) {
448 448
      int leftn=_data[a].left_neighbor;
449 449
      int rightn=_data[a].right_neighbor;
450 450
      _data[leftn].right_neighbor=rightn;
451 451
      _data[rightn].left_neighbor=leftn;
452 452
    }
453 453

	
454 454

	
455 455
    class Store {
456 456
      friend class FibHeap;
457 457

	
458 458
      Item name;
459 459
      int parent;
460 460
      int left_neighbor;
461 461
      int right_neighbor;
462 462
      int child;
463 463
      int degree;
464 464
      bool marked;
465 465
      bool in;
466 466
      Prio prio;
467 467

	
468 468
      Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
469 469
    };
470 470
  };
471 471

	
472 472
} //namespace lemon
473 473

	
474 474
#endif //LEMON_FIB_HEAP_H
475 475

	
Ignore white space 768 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_RADIX_HEAP_H
20 20
#define LEMON_RADIX_HEAP_H
21 21

	
22 22
///\ingroup heaps
23 23
///\file
24 24
///\brief Radix heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <lemon/error.h>
28 28

	
29 29
namespace lemon {
30 30

	
31 31

	
32 32
  /// \ingroup heaps
33 33
  ///
34 34
  /// \brief Radix heap data structure.
35 35
  ///
36 36
  /// This class implements the \e radix \e heap data structure.
37 37
  /// It practically conforms to the \ref concepts::Heap "heap concept",
38 38
  /// but it has some limitations due its special implementation.
39 39
  /// The type of the priorities must be \c int and the priority of an
40 40
  /// item cannot be decreased under the priority of the last removed item.
41 41
  ///
42 42
  /// \tparam IM A read-writable item map with \c int values, used
43 43
  /// internally to handle the cross references.
44 44
  template <typename IM>
45 45
  class RadixHeap {
46 46

	
47 47
  public:
48 48

	
49 49
    /// Type of the item-int map.
50 50
    typedef IM ItemIntMap;
51 51
    /// Type of the priorities.
52 52
    typedef int Prio;
53 53
    /// Type of the items stored in the heap.
54 54
    typedef typename ItemIntMap::Key Item;
55 55

	
56 56
    /// \brief Exception thrown by RadixHeap.
57 57
    ///
58 58
    /// This exception is thrown when an item is inserted into a
59 59
    /// RadixHeap with a priority smaller than the last erased one.
60 60
    /// \see RadixHeap
61
    class UnderFlowPriorityError : public Exception {
61
    class PriorityUnderflowError : public Exception {
62 62
    public:
63 63
      virtual const char* what() const throw() {
64
        return "lemon::RadixHeap::UnderFlowPriorityError";
64
        return "lemon::RadixHeap::PriorityUnderflowError";
65 65
      }
66 66
    };
67 67

	
68 68
    /// \brief Type to represent the states of the items.
69 69
    ///
70 70
    /// Each item has a state associated to it. It can be "in heap",
71 71
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
72 72
    /// heap's point of view, but may be useful to the user.
73 73
    ///
74 74
    /// The item-int map must be initialized in such way that it assigns
75 75
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
76 76
    enum State {
77 77
      IN_HEAP = 0,    ///< = 0.
78 78
      PRE_HEAP = -1,  ///< = -1.
79 79
      POST_HEAP = -2  ///< = -2.
80 80
    };
81 81

	
82 82
  private:
83 83

	
84 84
    struct RadixItem {
85 85
      int prev, next, box;
86 86
      Item item;
87 87
      int prio;
88 88
      RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
89 89
    };
90 90

	
91 91
    struct RadixBox {
92 92
      int first;
93 93
      int min, size;
94 94
      RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
95 95
    };
96 96

	
97
    std::vector<RadixItem> data;
98
    std::vector<RadixBox> boxes;
97
    std::vector<RadixItem> _data;
98
    std::vector<RadixBox> _boxes;
99 99

	
100 100
    ItemIntMap &_iim;
101 101

	
102 102
  public:
103 103

	
104 104
    /// \brief Constructor.
105 105
    ///
106 106
    /// Constructor.
107 107
    /// \param map A map that assigns \c int values to the items.
108 108
    /// It is used internally to handle the cross references.
109 109
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
110 110
    /// \param minimum The initial minimum value of the heap.
111 111
    /// \param capacity The initial capacity of the heap.
112 112
    RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
113 113
      : _iim(map)
114 114
    {
115
      boxes.push_back(RadixBox(minimum, 1));
116
      boxes.push_back(RadixBox(minimum + 1, 1));
117
      while (lower(boxes.size() - 1, capacity + minimum - 1)) {
115
      _boxes.push_back(RadixBox(minimum, 1));
116
      _boxes.push_back(RadixBox(minimum + 1, 1));
117
      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
118 118
        extend();
119 119
      }
120 120
    }
121 121

	
122 122
    /// \brief The number of items stored in the heap.
123 123
    ///
124 124
    /// This function returns the number of items stored in the heap.
125
    int size() const { return data.size(); }
125
    int size() const { return _data.size(); }
126 126

	
127 127
    /// \brief Check if the heap is empty.
128 128
    ///
129 129
    /// This function returns \c true if the heap is empty.
130
    bool empty() const { return data.empty(); }
130
    bool empty() const { return _data.empty(); }
131 131

	
132 132
    /// \brief Make the heap empty.
133 133
    ///
134 134
    /// This functon makes the heap empty.
135 135
    /// It does not change the cross reference map. If you want to reuse
136 136
    /// a heap that is not surely empty, you should first clear it and
137 137
    /// then you should set the cross reference map to \c PRE_HEAP
138 138
    /// for each item.
139 139
    /// \param minimum The minimum value of the heap.
140 140
    /// \param capacity The capacity of the heap.
141 141
    void clear(int minimum = 0, int capacity = 0) {
142
      data.clear(); boxes.clear();
143
      boxes.push_back(RadixBox(minimum, 1));
144
      boxes.push_back(RadixBox(minimum + 1, 1));
145
      while (lower(boxes.size() - 1, capacity + minimum - 1)) {
142
      _data.clear(); _boxes.clear();
143
      _boxes.push_back(RadixBox(minimum, 1));
144
      _boxes.push_back(RadixBox(minimum + 1, 1));
145
      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
146 146
        extend();
147 147
      }
148 148
    }
149 149

	
150 150
  private:
151 151

	
152 152
    bool upper(int box, Prio pr) {
153
      return pr < boxes[box].min;
153
      return pr < _boxes[box].min;
154 154
    }
155 155

	
156 156
    bool lower(int box, Prio pr) {
157
      return pr >= boxes[box].min + boxes[box].size;
157
      return pr >= _boxes[box].min + _boxes[box].size;
158 158
    }
159 159

	
160 160
    // Remove item from the box list
161 161
    void remove(int index) {
162
      if (data[index].prev >= 0) {
163
        data[data[index].prev].next = data[index].next;
162
      if (_data[index].prev >= 0) {
163
        _data[_data[index].prev].next = _data[index].next;
164 164
      } else {
165
        boxes[data[index].box].first = data[index].next;
165
        _boxes[_data[index].box].first = _data[index].next;
166 166
      }
167
      if (data[index].next >= 0) {
168
        data[data[index].next].prev = data[index].prev;
167
      if (_data[index].next >= 0) {
168
        _data[_data[index].next].prev = _data[index].prev;
169 169
      }
170 170
    }
171 171

	
172 172
    // Insert item into the box list
173 173
    void insert(int box, int index) {
174
      if (boxes[box].first == -1) {
175
        boxes[box].first = index;
176
        data[index].next = data[index].prev = -1;
174
      if (_boxes[box].first == -1) {
175
        _boxes[box].first = index;
176
        _data[index].next = _data[index].prev = -1;
177 177
      } else {
178
        data[index].next = boxes[box].first;
179
        data[boxes[box].first].prev = index;
180
        data[index].prev = -1;
181
        boxes[box].first = index;
178
        _data[index].next = _boxes[box].first;
179
        _data[_boxes[box].first].prev = index;
180
        _data[index].prev = -1;
181
        _boxes[box].first = index;
182 182
      }
183
      data[index].box = box;
183
      _data[index].box = box;
184 184
    }
185 185

	
186 186
    // Add a new box to the box list
187 187
    void extend() {
188
      int min = boxes.back().min + boxes.back().size;
189
      int bs = 2 * boxes.back().size;
190
      boxes.push_back(RadixBox(min, bs));
188
      int min = _boxes.back().min + _boxes.back().size;
189
      int bs = 2 * _boxes.back().size;
190
      _boxes.push_back(RadixBox(min, bs));
191 191
    }
192 192

	
193 193
    // Move an item up into the proper box.
194
    void bubble_up(int index) {
195
      if (!lower(data[index].box, data[index].prio)) return;
194
    void bubbleUp(int index) {
195
      if (!lower(_data[index].box, _data[index].prio)) return;
196 196
      remove(index);
197
      int box = findUp(data[index].box, data[index].prio);
197
      int box = findUp(_data[index].box, _data[index].prio);
198 198
      insert(box, index);
199 199
    }
200 200

	
201 201
    // Find up the proper box for the item with the given priority
202 202
    int findUp(int start, int pr) {
203 203
      while (lower(start, pr)) {
204
        if (++start == int(boxes.size())) {
204
        if (++start == int(_boxes.size())) {
205 205
          extend();
206 206
        }
207 207
      }
208 208
      return start;
209 209
    }
210 210

	
211 211
    // Move an item down into the proper box
212
    void bubble_down(int index) {
213
      if (!upper(data[index].box, data[index].prio)) return;
212
    void bubbleDown(int index) {
213
      if (!upper(_data[index].box, _data[index].prio)) return;
214 214
      remove(index);
215
      int box = findDown(data[index].box, data[index].prio);
215
      int box = findDown(_data[index].box, _data[index].prio);
216 216
      insert(box, index);
217 217
    }
218 218

	
219 219
    // Find down the proper box for the item with the given priority
220 220
    int findDown(int start, int pr) {
221 221
      while (upper(start, pr)) {
222
        if (--start < 0) throw UnderFlowPriorityError();
222
        if (--start < 0) throw PriorityUnderflowError();
223 223
      }
224 224
      return start;
225 225
    }
226 226

	
227 227
    // Find the first non-empty box
228 228
    int findFirst() {
229 229
      int first = 0;
230
      while (boxes[first].first == -1) ++first;
230
      while (_boxes[first].first == -1) ++first;
231 231
      return first;
232 232
    }
233 233

	
234 234
    // Gives back the minimum priority of the given box
235 235
    int minValue(int box) {
236
      int min = data[boxes[box].first].prio;
237
      for (int k = boxes[box].first; k != -1; k = data[k].next) {
238
        if (data[k].prio < min) min = data[k].prio;
236
      int min = _data[_boxes[box].first].prio;
237
      for (int k = _boxes[box].first; k != -1; k = _data[k].next) {
238
        if (_data[k].prio < min) min = _data[k].prio;
239 239
      }
240 240
      return min;
241 241
    }
242 242

	
243 243
    // Rearrange the items of the heap and make the first box non-empty
244 244
    void moveDown() {
245 245
      int box = findFirst();
246 246
      if (box == 0) return;
247 247
      int min = minValue(box);
248 248
      for (int i = 0; i <= box; ++i) {
249
        boxes[i].min = min;
250
        min += boxes[i].size;
249
        _boxes[i].min = min;
250
        min += _boxes[i].size;
251 251
      }
252
      int curr = boxes[box].first, next;
252
      int curr = _boxes[box].first, next;
253 253
      while (curr != -1) {
254
        next = data[curr].next;
255
        bubble_down(curr);
254
        next = _data[curr].next;
255
        bubbleDown(curr);
256 256
        curr = next;
257 257
      }
258 258
    }
259 259

	
260
    void relocate_last(int index) {
261
      if (index != int(data.size()) - 1) {
262
        data[index] = data.back();
263
        if (data[index].prev != -1) {
264
          data[data[index].prev].next = index;
260
    void relocateLast(int index) {
261
      if (index != int(_data.size()) - 1) {
262
        _data[index] = _data.back();
263
        if (_data[index].prev != -1) {
264
          _data[_data[index].prev].next = index;
265 265
        } else {
266
          boxes[data[index].box].first = index;
266
          _boxes[_data[index].box].first = index;
267 267
        }
268
        if (data[index].next != -1) {
269
          data[data[index].next].prev = index;
268
        if (_data[index].next != -1) {
269
          _data[_data[index].next].prev = index;
270 270
        }
271
        _iim[data[index].item] = index;
271
        _iim[_data[index].item] = index;
272 272
      }
273
      data.pop_back();
273
      _data.pop_back();
274 274
    }
275 275

	
276 276
  public:
277 277

	
278 278
    /// \brief Insert an item into the heap with the given priority.
279 279
    ///
280 280
    /// This function inserts the given item into the heap with the
281 281
    /// given priority.
282 282
    /// \param i The item to insert.
283 283
    /// \param p The priority of the item.
284 284
    /// \pre \e i must not be stored in the heap.
285 285
    /// \warning This method may throw an \c UnderFlowPriorityException.
286 286
    void push(const Item &i, const Prio &p) {
287
      int n = data.size();
287
      int n = _data.size();
288 288
      _iim.set(i, n);
289
      data.push_back(RadixItem(i, p));
290
      while (lower(boxes.size() - 1, p)) {
289
      _data.push_back(RadixItem(i, p));
290
      while (lower(_boxes.size() - 1, p)) {
291 291
        extend();
292 292
      }
293
      int box = findDown(boxes.size() - 1, p);
293
      int box = findDown(_boxes.size() - 1, p);
294 294
      insert(box, n);
295 295
    }
296 296

	
297 297
    /// \brief Return the item having minimum priority.
298 298
    ///
299 299
    /// This function returns the item having minimum priority.
300 300
    /// \pre The heap must be non-empty.
301 301
    Item top() const {
302 302
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
303
      return data[boxes[0].first].item;
303
      return _data[_boxes[0].first].item;
304 304
    }
305 305

	
306 306
    /// \brief The minimum priority.
307 307
    ///
308 308
    /// This function returns the minimum priority.
309 309
    /// \pre The heap must be non-empty.
310 310
    Prio prio() const {
311 311
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
312
      return data[boxes[0].first].prio;
312
      return _data[_boxes[0].first].prio;
313 313
     }
314 314

	
315 315
    /// \brief Remove the item having minimum priority.
316 316
    ///
317 317
    /// This function removes the item having minimum priority.
318 318
    /// \pre The heap must be non-empty.
319 319
    void pop() {
320 320
      moveDown();
321
      int index = boxes[0].first;
322
      _iim[data[index].item] = POST_HEAP;
321
      int index = _boxes[0].first;
322
      _iim[_data[index].item] = POST_HEAP;
323 323
      remove(index);
324
      relocate_last(index);
324
      relocateLast(index);
325 325
    }
326 326

	
327 327
    /// \brief Remove the given item from the heap.
328 328
    ///
329 329
    /// This function removes the given item from the heap if it is
330 330
    /// already stored.
331 331
    /// \param i The item to delete.
332 332
    /// \pre \e i must be in the heap.
333 333
    void erase(const Item &i) {
334 334
      int index = _iim[i];
335 335
      _iim[i] = POST_HEAP;
336 336
      remove(index);
337
      relocate_last(index);
337
      relocateLast(index);
338 338
   }
339 339

	
340 340
    /// \brief The priority of the given item.
341 341
    ///
342 342
    /// This function returns the priority of the given item.
343 343
    /// \param i The item.
344 344
    /// \pre \e i must be in the heap.
345 345
    Prio operator[](const Item &i) const {
346 346
      int idx = _iim[i];
347
      return data[idx].prio;
347
      return _data[idx].prio;
348 348
    }
349 349

	
350 350
    /// \brief Set the priority of an item or insert it, if it is
351 351
    /// not stored in the heap.
352 352
    ///
353 353
    /// This method sets the priority of the given item if it is
354 354
    /// already stored in the heap. Otherwise it inserts the given
355 355
    /// item into the heap with the given priority.
356 356
    /// \param i The item.
357 357
    /// \param p The priority.
358 358
    /// \pre \e i must be in the heap.
359 359
    /// \warning This method may throw an \c UnderFlowPriorityException.
360 360
    void set(const Item &i, const Prio &p) {
361 361
      int idx = _iim[i];
362 362
      if( idx < 0 ) {
363 363
        push(i, p);
364 364
      }
365
      else if( p >= data[idx].prio ) {
366
        data[idx].prio = p;
367
        bubble_up(idx);
365
      else if( p >= _data[idx].prio ) {
366
        _data[idx].prio = p;
367
        bubbleUp(idx);
368 368
      } else {
369
        data[idx].prio = p;
370
        bubble_down(idx);
369
        _data[idx].prio = p;
370
        bubbleDown(idx);
371 371
      }
372 372
    }
373 373

	
374 374
    /// \brief Decrease the priority of an item to the given value.
375 375
    ///
376 376
    /// This function decreases the priority of an item to the given value.
377 377
    /// \param i The item.
378 378
    /// \param p The priority.
379 379
    /// \pre \e i must be stored in the heap with priority at least \e p.
380 380
    /// \warning This method may throw an \c UnderFlowPriorityException.
381 381
    void decrease(const Item &i, const Prio &p) {
382 382
      int idx = _iim[i];
383
      data[idx].prio = p;
384
      bubble_down(idx);
383
      _data[idx].prio = p;
384
      bubbleDown(idx);
385 385
    }
386 386

	
387 387
    /// \brief Increase the priority of an item to the given value.
388 388
    ///
389 389
    /// This function increases the priority of an item to the given value.
390 390
    /// \param i The item.
391 391
    /// \param p The priority.
392 392
    /// \pre \e i must be stored in the heap with priority at most \e p.
393 393
    void increase(const Item &i, const Prio &p) {
394 394
      int idx = _iim[i];
395
      data[idx].prio = p;
396
      bubble_up(idx);
395
      _data[idx].prio = p;
396
      bubbleUp(idx);
397 397
    }
398 398

	
399 399
    /// \brief Return the state of an item.
400 400
    ///
401 401
    /// This method returns \c PRE_HEAP if the given item has never
402 402
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
403 403
    /// and \c POST_HEAP otherwise.
404 404
    /// In the latter case it is possible that the item will get back
405 405
    /// to the heap again.
406 406
    /// \param i The item.
407 407
    State state(const Item &i) const {
408 408
      int s = _iim[i];
409 409
      if( s >= 0 ) s = 0;
410 410
      return State(s);
411 411
    }
412 412

	
413 413
    /// \brief Set the state of an item in the heap.
414 414
    ///
415 415
    /// This function sets the state of the given item in the heap.
416 416
    /// It can be used to manually clear the heap when it is important
417 417
    /// to achive better time complexity.
418 418
    /// \param i The item.
419 419
    /// \param st The state. It should not be \c IN_HEAP.
420 420
    void state(const Item& i, State st) {
421 421
      switch (st) {
422 422
      case POST_HEAP:
423 423
      case PRE_HEAP:
424 424
        if (state(i) == IN_HEAP) {
425 425
          erase(i);
426 426
        }
427 427
        _iim[i] = st;
428 428
        break;
429 429
      case IN_HEAP:
430 430
        break;
431 431
      }
432 432
    }
433 433

	
434 434
  }; // class RadixHeap
435 435

	
436 436
} // namespace lemon
437 437

	
438 438
#endif // LEMON_RADIX_HEAP_H
0 comments (0 inline)