gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Rename heap structures (#301) - KaryHeap --> DHeap - FouraryHeap --> QuadHeap - BinomHeap --> BinomialHeap
3 2 3
default
8 files changed with 56 insertions and 55 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	lemon/lemon.pc.in \
3 3
	lemon/CMakeLists.txt \
4 4
	lemon/config.h.cmake
5 5

	
6 6
pkgconfig_DATA += lemon/lemon.pc
7 7

	
8 8
lib_LTLIBRARIES += lemon/libemon.la
9 9

	
10 10
lemon_libemon_la_SOURCES = \
11 11
	lemon/arg_parser.cc \
12 12
	lemon/base.cc \
13 13
	lemon/color.cc \
14 14
	lemon/lp_base.cc \
15 15
	lemon/lp_skeleton.cc \
16 16
	lemon/random.cc \
17 17
	lemon/bits/windows.cc
18 18

	
19 19
nodist_lemon_HEADERS = lemon/config.h	
20 20

	
21 21
lemon_libemon_la_CXXFLAGS = \
22 22
	$(AM_CXXFLAGS) \
23 23
	$(GLPK_CFLAGS) \
24 24
	$(CPLEX_CFLAGS) \
25 25
	$(SOPLEX_CXXFLAGS) \
26 26
	$(CLP_CXXFLAGS) \
27 27
	$(CBC_CXXFLAGS)
28 28

	
29 29
lemon_libemon_la_LDFLAGS = \
30 30
	$(GLPK_LIBS) \
31 31
	$(CPLEX_LIBS) \
32 32
	$(SOPLEX_LIBS) \
33 33
	$(CLP_LIBS) \
34 34
	$(CBC_LIBS)
35 35

	
36 36
if HAVE_GLPK
37 37
lemon_libemon_la_SOURCES += lemon/glpk.cc
38 38
endif
39 39

	
40 40
if HAVE_CPLEX
41 41
lemon_libemon_la_SOURCES += lemon/cplex.cc
42 42
endif
43 43

	
44 44
if HAVE_SOPLEX
45 45
lemon_libemon_la_SOURCES += lemon/soplex.cc
46 46
endif
47 47

	
48 48
if HAVE_CLP
49 49
lemon_libemon_la_SOURCES += lemon/clp.cc
50 50
endif
51 51

	
52 52
if HAVE_CBC
53 53
lemon_libemon_la_SOURCES += lemon/cbc.cc
54 54
endif
55 55

	
56 56
lemon_HEADERS += \
57 57
	lemon/adaptors.h \
58 58
	lemon/arg_parser.h \
59 59
	lemon/assert.h \
60 60
	lemon/bellman_ford.h \
61 61
	lemon/bfs.h \
62 62
	lemon/bin_heap.h \
63
	lemon/binom_heap.h \
63
	lemon/binomial_heap.h \
64 64
	lemon/bucket_heap.h \
65 65
	lemon/cbc.h \
66 66
	lemon/circulation.h \
67 67
	lemon/clp.h \
68 68
	lemon/color.h \
69 69
	lemon/concept_check.h \
70 70
	lemon/connectivity.h \
71 71
	lemon/counter.h \
72 72
	lemon/core.h \
73 73
	lemon/cplex.h \
74 74
	lemon/dfs.h \
75
	lemon/dheap.h \
75 76
	lemon/dijkstra.h \
76 77
	lemon/dim2.h \
77 78
	lemon/dimacs.h \
78 79
	lemon/edge_set.h \
79 80
	lemon/elevator.h \
80 81
	lemon/error.h \
81 82
	lemon/euler.h \
82 83
	lemon/fib_heap.h \
83
	lemon/fourary_heap.h \
84 84
	lemon/full_graph.h \
85 85
	lemon/glpk.h \
86 86
	lemon/gomory_hu.h \
87 87
	lemon/graph_to_eps.h \
88 88
	lemon/grid_graph.h \
89 89
	lemon/hypercube_graph.h \
90
	lemon/kary_heap.h \
91 90
	lemon/kruskal.h \
92 91
	lemon/hao_orlin.h \
93 92
	lemon/lgf_reader.h \
94 93
	lemon/lgf_writer.h \
95 94
	lemon/list_graph.h \
96 95
	lemon/lp.h \
97 96
	lemon/lp_base.h \
98 97
	lemon/lp_skeleton.h \
99 98
	lemon/maps.h \
100 99
	lemon/matching.h \
101 100
	lemon/math.h \
102 101
	lemon/min_cost_arborescence.h \
103 102
	lemon/nauty_reader.h \
104 103
	lemon/network_simplex.h \
105 104
	lemon/pairing_heap.h \
106 105
	lemon/path.h \
107 106
	lemon/preflow.h \
107
	lemon/quad_heap.h \
108 108
	lemon/radix_heap.h \
109 109
	lemon/radix_sort.h \
110 110
	lemon/random.h \
111 111
	lemon/smart_graph.h \
112 112
	lemon/soplex.h \
113 113
	lemon/suurballe.h \
114 114
	lemon/time_measure.h \
115 115
	lemon/tolerance.h \
116 116
	lemon/unionfind.h \
117 117
	lemon/bits/windows.h
118 118

	
119 119
bits_HEADERS += \
120 120
	lemon/bits/alteration_notifier.h \
121 121
	lemon/bits/array_map.h \
122 122
	lemon/bits/bezier.h \
123 123
	lemon/bits/default_map.h \
124 124
	lemon/bits/edge_set_extender.h \
125 125
	lemon/bits/enable_if.h \
126 126
	lemon/bits/graph_adaptor_extender.h \
127 127
	lemon/bits/graph_extender.h \
128 128
	lemon/bits/map_extender.h \
129 129
	lemon/bits/path_dump.h \
130 130
	lemon/bits/solver_bits.h \
131 131
	lemon/bits/traits.h \
132 132
	lemon/bits/variant.h \
133 133
	lemon/bits/vector_map.h
134 134

	
135 135
concept_HEADERS += \
136 136
	lemon/concepts/digraph.h \
137 137
	lemon/concepts/graph.h \
138 138
	lemon/concepts/graph_components.h \
139 139
	lemon/concepts/heap.h \
140 140
	lemon/concepts/maps.h \
141 141
	lemon/concepts/path.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
#ifndef LEMON_BINOM_HEAP_H
20
#define LEMON_BINOM_HEAP_H
19
#ifndef LEMON_BINOMIAL_HEAP_H
20
#define LEMON_BINOMIAL_HEAP_H
21 21

	
22 22
///\file
23 23
///\ingroup heaps
24 24
///\brief Binomial Heap implementation.
25 25

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

	
32 32
namespace lemon {
33 33

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

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

	
81 81
  private:
82 82
    class Store;
83 83

	
84 84
    std::vector<Store> _data;
85 85
    int _min, _head;
86 86
    ItemIntMap &_iim;
87 87
    Compare _comp;
88 88
    int _num_items;
89 89

	
90 90
  public:
91 91
    /// \brief Constructor.
92 92
    ///
93 93
    /// Constructor.
94 94
    /// \param map A map that assigns \c int values to the items.
95 95
    /// It is used internally to handle the cross references.
96 96
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
97
    explicit BinomHeap(ItemIntMap &map)
97
    explicit BinomialHeap(ItemIntMap &map)
98 98
      : _min(0), _head(-1), _iim(map), _num_items(0) {}
99 99

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

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

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

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

	
131 131
    /// \brief Set the priority of an item or insert it, if it is
132 132
    /// not stored in the heap.
133 133
    ///
134 134
    /// This method sets the priority of the given item if it is
135 135
    /// already stored in the heap. Otherwise it inserts the given
136 136
    /// item into the heap with the given priority.
137 137
    /// \param item The item.
138 138
    /// \param value The priority.
139 139
    void set (const Item& item, const Prio& value) {
140 140
      int i=_iim[item];
141 141
      if ( i >= 0 && _data[i].in ) {
142 142
        if ( _comp(value, _data[i].prio) ) decrease(item, value);
143 143
        if ( _comp(_data[i].prio, value) ) increase(item, value);
144 144
      } else push(item, value);
145 145
    }
146 146

	
147 147
    /// \brief Insert an item into the heap with the given priority.
148 148
    ///
149 149
    /// This function inserts the given item into the heap with the
150 150
    /// given priority.
151 151
    /// \param item The item to insert.
152 152
    /// \param value The priority of the item.
153 153
    /// \pre \e item must not be stored in the heap.
154 154
    void push (const Item& item, const Prio& value) {
155 155
      int i=_iim[item];
156 156
      if ( i<0 ) {
157 157
        int s=_data.size();
158 158
        _iim.set( item,s );
159 159
        Store st;
160 160
        st.name=item;
161 161
        st.prio=value;
162 162
        _data.push_back(st);
163 163
        i=s;
164 164
      }
165 165
      else {
166 166
        _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
167 167
        _data[i].degree=0;
168 168
        _data[i].in=true;
169 169
        _data[i].prio=value;
170 170
      }
171 171

	
172 172
      if( 0==_num_items ) {
173 173
        _head=i;
174 174
        _min=i;
175 175
      } else {
176 176
        merge(i);
177 177
        if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
178 178
      }
179 179
      ++_num_items;
180 180
    }
181 181

	
182 182
    /// \brief Return the item having minimum priority.
183 183
    ///
184 184
    /// This function returns the item having minimum priority.
185 185
    /// \pre The heap must be non-empty.
186 186
    Item top() const { return _data[_min].name; }
187 187

	
188 188
    /// \brief The minimum priority.
189 189
    ///
190 190
    /// This function returns the minimum priority.
191 191
    /// \pre The heap must be non-empty.
192 192
    Prio prio() const { return _data[_min].prio; }
193 193

	
194 194
    /// \brief The priority of the given item.
195 195
    ///
196 196
    /// This function returns the priority of the given item.
197 197
    /// \param item The item.
198 198
    /// \pre \e item must be in the heap.
199 199
    const Prio& operator[](const Item& item) const {
200 200
      return _data[_iim[item]].prio;
201 201
    }
202 202

	
203 203
    /// \brief Remove the item having minimum priority.
204 204
    ///
205 205
    /// This function removes the item having minimum priority.
206 206
    /// \pre The heap must be non-empty.
207 207
    void pop() {
208 208
      _data[_min].in=false;
209 209

	
210 210
      int head_child=-1;
211 211
      if ( _data[_min].child!=-1 ) {
212 212
        int child=_data[_min].child;
213 213
        int neighb;
214 214
        while( child!=-1 ) {
215 215
          neighb=_data[child].right_neighbor;
216 216
          _data[child].parent=-1;
217 217
          _data[child].right_neighbor=head_child;
218 218
          head_child=child;
219 219
          child=neighb;
220 220
        }
221 221
      }
222 222

	
223 223
      if ( _data[_head].right_neighbor==-1 ) {
224 224
        // there was only one root
225 225
        _head=head_child;
226 226
      }
227 227
      else {
228 228
        // there were more roots
229 229
        if( _head!=_min )  { unlace(_min); }
230 230
        else { _head=_data[_head].right_neighbor; }
231 231
        merge(head_child);
232 232
      }
233 233
      _min=findMin();
234 234
      --_num_items;
235 235
    }
236 236

	
237 237
    /// \brief Remove the given item from the heap.
238 238
    ///
239 239
    /// This function removes the given item from the heap if it is
240 240
    /// already stored.
241 241
    /// \param item The item to delete.
242 242
    /// \pre \e item must be in the heap.
243 243
    void erase (const Item& item) {
244 244
      int i=_iim[item];
245 245
      if ( i >= 0 && _data[i].in ) {
246 246
        decrease( item, _data[_min].prio-1 );
247 247
        pop();
248 248
      }
249 249
    }
250 250

	
251 251
    /// \brief Decrease the priority of an item to the given value.
252 252
    ///
253 253
    /// This function decreases the priority of an item to the given value.
254 254
    /// \param item The item.
255 255
    /// \param value The priority.
256 256
    /// \pre \e item must be stored in the heap with priority at least \e value.
257 257
    void decrease (Item item, const Prio& value) {
258 258
      int i=_iim[item];
259 259
      int p=_data[i].parent;
260 260
      _data[i].prio=value;
261 261
      
262 262
      while( p!=-1 && _comp(value, _data[p].prio) ) {
263 263
        _data[i].name=_data[p].name;
264 264
        _data[i].prio=_data[p].prio;
265 265
        _data[p].name=item;
266 266
        _data[p].prio=value;
267 267
        _iim[_data[i].name]=i;
268 268
        i=p;
269 269
        p=_data[p].parent;
270 270
      }
271 271
      _iim[item]=i;
272 272
      if ( _comp(value, _data[_min].prio) ) _min=i;
273 273
    }
274 274

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

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

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

	
324 324
  private:
325 325
    
326 326
    // Find the minimum of the roots
327 327
    int findMin() {
328 328
      if( _head!=-1 ) {
329 329
        int min_loc=_head, min_val=_data[_head].prio;
330 330
        for( int x=_data[_head].right_neighbor; x!=-1;
331 331
             x=_data[x].right_neighbor ) {
332 332
          if( _comp( _data[x].prio,min_val ) ) {
333 333
            min_val=_data[x].prio;
334 334
            min_loc=x;
335 335
          }
336 336
        }
337 337
        return min_loc;
338 338
      }
339 339
      else return -1;
340 340
    }
341 341

	
342 342
    // Merge the heap with another heap starting at the given position
343 343
    void merge(int a) {
344 344
      if( _head==-1 || a==-1 ) return;
345 345
      if( _data[a].right_neighbor==-1 &&
346 346
          _data[a].degree<=_data[_head].degree ) {
347 347
        _data[a].right_neighbor=_head;
348 348
        _head=a;
349 349
      } else {
350 350
        interleave(a);
351 351
      }
352 352
      if( _data[_head].right_neighbor==-1 ) return;
353 353
      
354 354
      int x=_head;
355 355
      int x_prev=-1, x_next=_data[x].right_neighbor;
356 356
      while( x_next!=-1 ) {
357 357
        if( _data[x].degree!=_data[x_next].degree ||
358 358
            ( _data[x_next].right_neighbor!=-1 &&
359 359
              _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
360 360
          x_prev=x;
361 361
          x=x_next;
362 362
        }
363 363
        else {
364 364
          if( _comp(_data[x_next].prio,_data[x].prio) ) {
365 365
            if( x_prev==-1 ) {
366 366
              _head=x_next;
367 367
            } else {
368 368
              _data[x_prev].right_neighbor=x_next;
369 369
            }
370 370
            fuse(x,x_next);
371 371
            x=x_next;
372 372
          }
373 373
          else {
374 374
            _data[x].right_neighbor=_data[x_next].right_neighbor;
375 375
            fuse(x_next,x);
376 376
          }
377 377
        }
378 378
        x_next=_data[x].right_neighbor;
379 379
      }
380 380
    }
381 381

	
382 382
    // Interleave the elements of the given list into the list of the roots
383 383
    void interleave(int a) {
384 384
      int p=_head, q=a;
385 385
      int curr=_data.size();
386 386
      _data.push_back(Store());
387 387
      
388 388
      while( p!=-1 || q!=-1 ) {
389 389
        if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
390 390
          _data[curr].right_neighbor=p;
391 391
          curr=p;
392 392
          p=_data[p].right_neighbor;
393 393
        }
394 394
        else {
395 395
          _data[curr].right_neighbor=q;
396 396
          curr=q;
397 397
          q=_data[q].right_neighbor;
398 398
        }
399 399
      }
400 400
      
401 401
      _head=_data.back().right_neighbor;
402 402
      _data.pop_back();
403 403
    }
404 404

	
405 405
    // Lace node a under node b
406 406
    void fuse(int a, int b) {
407 407
      _data[a].parent=b;
408 408
      _data[a].right_neighbor=_data[b].child;
409 409
      _data[b].child=a;
410 410

	
411 411
      ++_data[b].degree;
412 412
    }
413 413

	
414 414
    // Unlace node a (if it has siblings)
415 415
    void unlace(int a) {
416 416
      int neighb=_data[a].right_neighbor;
417 417
      int other=_head;
418 418

	
419 419
      while( _data[other].right_neighbor!=a )
420 420
        other=_data[other].right_neighbor;
421 421
      _data[other].right_neighbor=neighb;
422 422
    }
423 423

	
424 424
  private:
425 425

	
426 426
    class Store {
427
      friend class BinomHeap;
427
      friend class BinomialHeap;
428 428

	
429 429
      Item name;
430 430
      int parent;
431 431
      int right_neighbor;
432 432
      int child;
433 433
      int degree;
434 434
      bool in;
435 435
      Prio prio;
436 436

	
437 437
      Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
438 438
        in(true) {}
439 439
    };
440 440
  };
441 441

	
442 442
} //namespace lemon
443 443

	
444
#endif //LEMON_BINOM_HEAP_H
444
#endif //LEMON_BINOMIAL_HEAP_H
445 445

	
Ignore white space 6144 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
#ifndef LEMON_KARY_HEAP_H
20
#define LEMON_KARY_HEAP_H
19
#ifndef LEMON_DHEAP_H
20
#define LEMON_DHEAP_H
21 21

	
22 22
///\ingroup heaps
23 23
///\file
24
///\brief Fourary heap implementation.
24
///\brief D-ary 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
  ///\brief K-ary heap data structure.
34
  ///\brief D-ary heap data structure.
35 35
  ///
36
  /// This class implements the \e K-ary \e heap data structure.
36
  /// This class implements the \e D-ary \e heap data structure.
37 37
  /// It fully conforms to the \ref concepts::Heap "heap concept".
38 38
  ///
39
  /// The \ref KaryHeap "K-ary heap" is a generalization of the
39
  /// The \ref DHeap "D-ary heap" is a generalization of the
40 40
  /// \ref BinHeap "binary heap" structure, its nodes have at most
41
  /// \c K children, instead of two.
42
  /// \ref BinHeap and \ref FouraryHeap are specialized implementations
43
  /// of this structure for <tt>K=2</tt> and <tt>K=4</tt>, respectively.
41
  /// \c D children, instead of two.
42
  /// \ref BinHeap and \ref QuadHeap are specialized implementations
43
  /// of this structure for <tt>D=2</tt> and <tt>D=4</tt>, respectively.
44 44
  ///
45 45
  /// \tparam PR Type of the priorities of the items.
46 46
  /// \tparam IM A read-writable item map with \c int values, used
47 47
  /// internally to handle the cross references.
48
  /// \tparam K The degree of the heap, each node have at most \e K
48
  /// \tparam D The degree of the heap, each node have at most \e D
49 49
  /// children. The default is 16. Powers of two are suggested to use
50 50
  /// so that the multiplications and divisions needed to traverse the
51 51
  /// nodes of the heap could be performed faster.
52 52
  /// \tparam CMP A functor class for comparing the priorities.
53 53
  /// The default is \c std::less<PR>.
54 54
  ///
55 55
  ///\sa BinHeap
56 56
  ///\sa FouraryHeap
57 57
#ifdef DOXYGEN
58
  template <typename PR, typename IM, int K, typename CMP>
58
  template <typename PR, typename IM, int D, typename CMP>
59 59
#else
60
  template <typename PR, typename IM, int K = 16,
60
  template <typename PR, typename IM, int D = 16,
61 61
            typename CMP = std::less<PR> >
62 62
#endif
63
  class KaryHeap {
63
  class DHeap {
64 64
  public:
65 65
    /// Type of the item-int map.
66 66
    typedef IM ItemIntMap;
67 67
    /// Type of the priorities.
68 68
    typedef PR Prio;
69 69
    /// Type of the items stored in the heap.
70 70
    typedef typename ItemIntMap::Key Item;
71 71
    /// Type of the item-priority pairs.
72 72
    typedef std::pair<Item,Prio> Pair;
73 73
    /// Functor type for comparing the priorities.
74 74
    typedef CMP Compare;
75 75

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

	
90 90
  private:
91 91
    std::vector<Pair> _data;
92 92
    Compare _comp;
93 93
    ItemIntMap &_iim;
94 94

	
95 95
  public:
96 96
    /// \brief Constructor.
97 97
    ///
98 98
    /// Constructor.
99 99
    /// \param map A map that assigns \c int values to the items.
100 100
    /// It is used internally to handle the cross references.
101 101
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
102
    explicit KaryHeap(ItemIntMap &map) : _iim(map) {}
102
    explicit DHeap(ItemIntMap &map) : _iim(map) {}
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 comp The function object used for comparing the priorities.
111
    KaryHeap(ItemIntMap &map, const Compare &comp)
111
    DHeap(ItemIntMap &map, const Compare &comp)
112 112
      : _iim(map), _comp(comp) {}
113 113

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

	
119 119
    /// \brief Check if the heap is empty.
120 120
    ///
121 121
    /// This function returns \c true if the heap is empty.
122 122
    bool empty() const { return _data.empty(); }
123 123

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

	
133 133
  private:
134
    int parent(int i) { return (i-1)/K; }
135
    int firstChild(int i) { return K*i+1; }
134
    int parent(int i) { return (i-1)/D; }
135
    int firstChild(int i) { return D*i+1; }
136 136

	
137 137
    bool less(const Pair &p1, const Pair &p2) const {
138 138
      return _comp(p1.second, p2.second);
139 139
    }
140 140

	
141 141
    void bubbleUp(int hole, Pair p) {
142 142
      int par = parent(hole);
143 143
      while( hole>0 && less(p,_data[par]) ) {
144 144
        move(_data[par],hole);
145 145
        hole = par;
146 146
        par = parent(hole);
147 147
      }
148 148
      move(p, hole);
149 149
    }
150 150

	
151 151
    void bubbleDown(int hole, Pair p, int length) {
152 152
      if( length>1 ) {
153 153
        int child = firstChild(hole);
154
        while( child+K<=length ) {
154
        while( child+D<=length ) {
155 155
          int min=child;
156
          for (int i=1; i<K; ++i) {
156
          for (int i=1; i<D; ++i) {
157 157
            if( less(_data[child+i], _data[min]) )
158 158
              min=child+i;
159 159
          }
160 160
          if( !less(_data[min], p) )
161 161
            goto ok;
162 162
          move(_data[min], hole);
163 163
          hole = min;
164 164
          child = firstChild(hole);
165 165
        }
166 166
        if ( child<length ) {
167 167
          int min = child;
168 168
          while (++child < length) {
169 169
            if( less(_data[child], _data[min]) )
170 170
              min=child;
171 171
          }
172 172
          if( less(_data[min], p) ) {
173 173
            move(_data[min], hole);
174 174
            hole = min;
175 175
          }
176 176
        }
177 177
      }
178 178
    ok:
179 179
      move(p, hole);
180 180
    }
181 181

	
182 182
    void move(const Pair &p, int i) {
183 183
      _data[i] = p;
184 184
      _iim.set(p.first, i);
185 185
    }
186 186

	
187 187
  public:
188 188
    /// \brief Insert a pair of item and priority into the heap.
189 189
    ///
190 190
    /// This function inserts \c p.first to the heap with priority
191 191
    /// \c p.second.
192 192
    /// \param p The pair to insert.
193 193
    /// \pre \c p.first must not be stored in the heap.
194 194
    void push(const Pair &p) {
195 195
      int n = _data.size();
196 196
      _data.resize(n+1);
197 197
      bubbleUp(n, p);
198 198
    }
199 199

	
200 200
    /// \brief Insert an item into the heap with the given priority.
201 201
    ///
202 202
    /// This function inserts the given item into the heap with the
203 203
    /// given priority.
204 204
    /// \param i The item to insert.
205 205
    /// \param p The priority of the item.
206 206
    /// \pre \e i must not be stored in the heap.
207 207
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
208 208

	
209 209
    /// \brief Return the item having minimum priority.
210 210
    ///
211 211
    /// This function returns the item having minimum priority.
212 212
    /// \pre The heap must be non-empty.
213 213
    Item top() const { return _data[0].first; }
214 214

	
215 215
    /// \brief The minimum priority.
216 216
    ///
217 217
    /// This function returns the minimum priority.
218 218
    /// \pre The heap must be non-empty.
219 219
    Prio prio() const { return _data[0].second; }
220 220

	
221 221
    /// \brief Remove the item having minimum priority.
222 222
    ///
223 223
    /// This function removes the item having minimum priority.
224 224
    /// \pre The heap must be non-empty.
225 225
    void pop() {
226 226
      int n = _data.size()-1;
227 227
      _iim.set(_data[0].first, POST_HEAP);
228 228
      if (n>0) bubbleDown(0, _data[n], n);
229 229
      _data.pop_back();
230 230
    }
231 231

	
232 232
    /// \brief Remove the given item from the heap.
233 233
    ///
234 234
    /// This function removes the given item from the heap if it is
235 235
    /// already stored.
236 236
    /// \param i The item to delete.
237 237
    /// \pre \e i must be in the heap.
238 238
    void erase(const Item &i) {
239 239
      int h = _iim[i];
240 240
      int n = _data.size()-1;
241 241
      _iim.set(_data[h].first, POST_HEAP);
242 242
      if( h<n ) {
243 243
        if( less(_data[parent(h)], _data[n]) )
244 244
          bubbleDown(h, _data[n], n);
245 245
        else
246 246
          bubbleUp(h, _data[n]);
247 247
      }
248 248
      _data.pop_back();
249 249
    }
250 250

	
251 251
    /// \brief The priority of the given item.
252 252
    ///
253 253
    /// This function returns the priority of the given item.
254 254
    /// \param i The item.
255 255
    /// \pre \e i must be in the heap.
256 256
    Prio operator[](const Item &i) const {
257 257
      int idx = _iim[i];
258 258
      return _data[idx].second;
259 259
    }
260 260

	
261 261
    /// \brief Set the priority of an item or insert it, if it is
262 262
    /// not stored in the heap.
263 263
    ///
264 264
    /// This method sets the priority of the given item if it is
265 265
    /// already stored in the heap. Otherwise it inserts the given
266 266
    /// item into the heap with the given priority.
267 267
    /// \param i The item.
268 268
    /// \param p The priority.
269 269
    void set(const Item &i, const Prio &p) {
270 270
      int idx = _iim[i];
271 271
      if( idx<0 )
272 272
        push(i,p);
273 273
      else if( _comp(p, _data[idx].second) )
274 274
        bubbleUp(idx, Pair(i,p));
275 275
      else
276 276
        bubbleDown(idx, Pair(i,p), _data.size());
277 277
    }
278 278

	
279 279
    /// \brief Decrease the priority of an item to the given value.
280 280
    ///
281 281
    /// This function decreases the priority of an item to the given value.
282 282
    /// \param i The item.
283 283
    /// \param p The priority.
284 284
    /// \pre \e i must be stored in the heap with priority at least \e p.
285 285
    void decrease(const Item &i, const Prio &p) {
286 286
      int idx = _iim[i];
287 287
      bubbleUp(idx, Pair(i,p));
288 288
    }
289 289

	
290 290
    /// \brief Increase the priority of an item to the given value.
291 291
    ///
292 292
    /// This function increases the priority of an item to the given value.
293 293
    /// \param i The item.
294 294
    /// \param p The priority.
295 295
    /// \pre \e i must be stored in the heap with priority at most \e p.
296 296
    void increase(const Item &i, const Prio &p) {
297 297
      int idx = _iim[i];
298 298
      bubbleDown(idx, Pair(i,p), _data.size());
299 299
    }
300 300

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

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

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

	
348
  }; // class KaryHeap
348
  }; // class DHeap
349 349

	
350 350
} // namespace lemon
351 351

	
352
#endif // LEMON_KARY_HEAP_H
352
#endif // LEMON_DHEAP_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
#ifndef LEMON_FOURARY_HEAP_H
20
#define LEMON_FOURARY_HEAP_H
19
#ifndef LEMON_QUAD_HEAP_H
20
#define LEMON_QUAD_HEAP_H
21 21

	
22 22
///\ingroup heaps
23 23
///\file
24
///\brief Fourary heap implementation.
24
///\brief Fourary (quaternary) 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
  ///\brief Fourary heap data structure.
34
  ///\brief Fourary (quaternary) heap data structure.
35 35
  ///
36
  /// This class implements the \e fourary \e heap data structure.
36
  /// This class implements the \e Fourary (\e quaternary) \e heap
37
  /// data structure.
37 38
  /// It fully conforms to the \ref concepts::Heap "heap concept".
38 39
  ///
39
  /// The fourary heap is a specialization of the \ref KaryHeap "K-ary heap"
40
  /// for <tt>K=4</tt>. It is similar to the \ref BinHeap "binary heap",
40
  /// The fourary heap is a specialization of the \ref DHeap "D-ary heap"
41
  /// for <tt>D=4</tt>. It is similar to the \ref BinHeap "binary heap",
41 42
  /// but its nodes have at most four children, instead of two.
42 43
  ///
43 44
  /// \tparam PR Type of the priorities of the items.
44 45
  /// \tparam IM A read-writable item map with \c int values, used
45 46
  /// internally to handle the cross references.
46 47
  /// \tparam CMP A functor class for comparing the priorities.
47 48
  /// The default is \c std::less<PR>.
48 49
  ///
49 50
  ///\sa BinHeap
50
  ///\sa KaryHeap
51
  ///\sa DHeap
51 52
#ifdef DOXYGEN
52 53
  template <typename PR, typename IM, typename CMP>
53 54
#else
54 55
  template <typename PR, typename IM, typename CMP = std::less<PR> >
55 56
#endif
56
  class FouraryHeap {
57
  class QuadHeap {
57 58
  public:
58 59
    /// Type of the item-int map.
59 60
    typedef IM ItemIntMap;
60 61
    /// Type of the priorities.
61 62
    typedef PR Prio;
62 63
    /// Type of the items stored in the heap.
63 64
    typedef typename ItemIntMap::Key Item;
64 65
    /// Type of the item-priority pairs.
65 66
    typedef std::pair<Item,Prio> Pair;
66 67
    /// Functor type for comparing the priorities.
67 68
    typedef CMP Compare;
68 69

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

	
83 84
  private:
84 85
    std::vector<Pair> _data;
85 86
    Compare _comp;
86 87
    ItemIntMap &_iim;
87 88

	
88 89
  public:
89 90
    /// \brief Constructor.
90 91
    ///
91 92
    /// Constructor.
92 93
    /// \param map A map that assigns \c int values to the items.
93 94
    /// It is used internally to handle the cross references.
94 95
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
95
    explicit FouraryHeap(ItemIntMap &map) : _iim(map) {}
96
    explicit QuadHeap(ItemIntMap &map) : _iim(map) {}
96 97

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

	
107 108
    /// \brief The number of items stored in the heap.
108 109
    ///
109 110
    /// This function returns the number of items stored in the heap.
110 111
    int size() const { return _data.size(); }
111 112

	
112 113
    /// \brief Check if the heap is empty.
113 114
    ///
114 115
    /// This function returns \c true if the heap is empty.
115 116
    bool empty() const { return _data.empty(); }
116 117

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

	
126 127
  private:
127 128
    static int parent(int i) { return (i-1)/4; }
128 129
    static int firstChild(int i) { return 4*i+1; }
129 130

	
130 131
    bool less(const Pair &p1, const Pair &p2) const {
131 132
      return _comp(p1.second, p2.second);
132 133
    }
133 134

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

	
144 145
    void bubbleDown(int hole, Pair p, int length) {
145 146
      if( length>1 ) {
146 147
        int child = firstChild(hole);
147 148
        while( child+3<length ) {
148 149
          int min=child;
149 150
          if( less(_data[++child], _data[min]) ) min=child;
150 151
          if( less(_data[++child], _data[min]) ) min=child;
151 152
          if( less(_data[++child], _data[min]) ) min=child;
152 153
          if( !less(_data[min], p) )
153 154
            goto ok;
154 155
          move(_data[min], hole);
155 156
          hole = min;
156 157
          child = firstChild(hole);
157 158
        }
158 159
        if ( child<length ) {
159 160
          int min = child;
160 161
          if( ++child<length && less(_data[child], _data[min]) ) min=child;
161 162
          if( ++child<length && less(_data[child], _data[min]) ) min=child;
162 163
          if( less(_data[min], p) ) {
163 164
            move(_data[min], hole);
164 165
            hole = min;
165 166
          }
166 167
        }
167 168
      }
168 169
    ok:
169 170
      move(p, hole);
170 171
    }
171 172

	
172 173
    void move(const Pair &p, int i) {
173 174
      _data[i] = p;
174 175
      _iim.set(p.first, i);
175 176
    }
176 177

	
177 178
  public:
178 179
    /// \brief Insert a pair of item and priority into the heap.
179 180
    ///
180 181
    /// This function inserts \c p.first to the heap with priority
181 182
    /// \c p.second.
182 183
    /// \param p The pair to insert.
183 184
    /// \pre \c p.first must not be stored in the heap.
184 185
    void push(const Pair &p) {
185 186
      int n = _data.size();
186 187
      _data.resize(n+1);
187 188
      bubbleUp(n, p);
188 189
    }
189 190

	
190 191
    /// \brief Insert an item into the heap with the given priority.
191 192
    ///
192 193
    /// This function inserts the given item into the heap with the
193 194
    /// given priority.
194 195
    /// \param i The item to insert.
195 196
    /// \param p The priority of the item.
196 197
    /// \pre \e i must not be stored in the heap.
197 198
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
198 199

	
199 200
    /// \brief Return the item having minimum priority.
200 201
    ///
201 202
    /// This function returns the item having minimum priority.
202 203
    /// \pre The heap must be non-empty.
203 204
    Item top() const { return _data[0].first; }
204 205

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

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

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

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

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

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

	
280 281
    /// \brief Increase the priority of an item to the given value.
281 282
    ///
282 283
    /// This function increases the priority of an item to the given value.
283 284
    /// \param i The item.
284 285
    /// \param p The priority.
285 286
    /// \pre \e i must be stored in the heap with priority at most \e p.
286 287
    void increase(const Item &i, const Prio &p) {
287 288
      int idx = _iim[i];
288 289
      bubbleDown(idx, Pair(i,p), _data.size());
289 290
    }
290 291

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

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

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

	
338
  }; // class FouraryHeap
339
  }; // class QuadHeap
339 340

	
340 341
} // namespace lemon
341 342

	
342 343
#endif // LEMON_FOURARY_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
#include <iostream>
20 20
#include <fstream>
21 21
#include <string>
22 22
#include <vector>
23 23

	
24 24
#include <lemon/concept_check.h>
25 25
#include <lemon/concepts/heap.h>
26 26

	
27 27
#include <lemon/smart_graph.h>
28 28
#include <lemon/lgf_reader.h>
29 29
#include <lemon/dijkstra.h>
30 30
#include <lemon/maps.h>
31 31

	
32 32
#include <lemon/bin_heap.h>
33
#include <lemon/fourary_heap.h>
34
#include <lemon/kary_heap.h>
33
#include <lemon/quad_heap.h>
34
#include <lemon/dheap.h>
35 35
#include <lemon/fib_heap.h>
36 36
#include <lemon/pairing_heap.h>
37 37
#include <lemon/radix_heap.h>
38
#include <lemon/binom_heap.h>
38
#include <lemon/binomial_heap.h>
39 39
#include <lemon/bucket_heap.h>
40 40

	
41 41
#include "test_tools.h"
42 42

	
43 43
using namespace lemon;
44 44
using namespace lemon::concepts;
45 45

	
46 46
typedef ListDigraph Digraph;
47 47
DIGRAPH_TYPEDEFS(Digraph);
48 48

	
49 49
char test_lgf[] =
50 50
  "@nodes\n"
51 51
  "label\n"
52 52
  "0\n"
53 53
  "1\n"
54 54
  "2\n"
55 55
  "3\n"
56 56
  "4\n"
57 57
  "5\n"
58 58
  "6\n"
59 59
  "7\n"
60 60
  "8\n"
61 61
  "9\n"
62 62
  "@arcs\n"
63 63
  "                label   capacity\n"
64 64
  "0       5       0       94\n"
65 65
  "3       9       1       11\n"
66 66
  "8       7       2       83\n"
67 67
  "1       2       3       94\n"
68 68
  "5       7       4       35\n"
69 69
  "7       4       5       84\n"
70 70
  "9       5       6       38\n"
71 71
  "0       4       7       96\n"
72 72
  "6       7       8       6\n"
73 73
  "3       1       9       27\n"
74 74
  "5       2       10      77\n"
75 75
  "5       6       11      69\n"
76 76
  "6       5       12      41\n"
77 77
  "4       6       13      70\n"
78 78
  "3       2       14      45\n"
79 79
  "7       9       15      93\n"
80 80
  "5       9       16      50\n"
81 81
  "9       0       17      94\n"
82 82
  "9       6       18      67\n"
83 83
  "0       9       19      86\n"
84 84
  "@attributes\n"
85 85
  "source 3\n";
86 86

	
87 87
int test_seq[] = { 2, 28, 19, 27, 33, 25, 13, 41, 10, 26,  1,  9,  4, 34};
88 88
int test_inc[] = {20, 28, 34, 16,  0, 46, 44,  0, 42, 32, 14,  8,  6, 37};
89 89

	
90 90
int test_len = sizeof(test_seq) / sizeof(test_seq[0]);
91 91

	
92 92
template <typename Heap>
93 93
void heapSortTest() {
94 94
  RangeMap<int> map(test_len, -1);
95 95
  Heap heap(map);
96 96

	
97 97
  std::vector<int> v(test_len);
98 98
  for (int i = 0; i < test_len; ++i) {
99 99
    v[i] = test_seq[i];
100 100
    heap.push(i, v[i]);
101 101
  }
102 102
  std::sort(v.begin(), v.end());
103 103
  for (int i = 0; i < test_len; ++i) {
104 104
    check(v[i] == heap.prio(), "Wrong order in heap sort.");
105 105
    heap.pop();
106 106
  }
107 107
}
108 108

	
109 109
template <typename Heap>
110 110
void heapIncreaseTest() {
111 111
  RangeMap<int> map(test_len, -1);
112 112

	
113 113
  Heap heap(map);
114 114

	
115 115
  std::vector<int> v(test_len);
116 116
  for (int i = 0; i < test_len; ++i) {
117 117
    v[i] = test_seq[i];
118 118
    heap.push(i, v[i]);
119 119
  }
120 120
  for (int i = 0; i < test_len; ++i) {
121 121
    v[i] += test_inc[i];
122 122
    heap.increase(i, v[i]);
123 123
  }
124 124
  std::sort(v.begin(), v.end());
125 125
  for (int i = 0; i < test_len; ++i) {
126 126
    check(v[i] == heap.prio(), "Wrong order in heap increase test.");
127 127
    heap.pop();
128 128
  }
129 129
}
130 130

	
131 131
template <typename Heap>
132 132
void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
133 133
                      Node source) {
134 134

	
135 135
  typename Dijkstra<Digraph, IntArcMap>::template SetStandardHeap<Heap>::
136 136
    Create dijkstra(digraph, length);
137 137

	
138 138
  dijkstra.run(source);
139 139

	
140 140
  for(ArcIt a(digraph); a != INVALID; ++a) {
141 141
    Node s = digraph.source(a);
142 142
    Node t = digraph.target(a);
143 143
    if (dijkstra.reached(s)) {
144 144
      check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
145 145
             "Error in shortest path tree.");
146 146
    }
147 147
  }
148 148

	
149 149
  for(NodeIt n(digraph); n != INVALID; ++n) {
150 150
    if ( dijkstra.reached(n) && dijkstra.predArc(n) != INVALID ) {
151 151
      Arc a = dijkstra.predArc(n);
152 152
      Node s = digraph.source(a);
153 153
      check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
154 154
             "Error in shortest path tree.");
155 155
    }
156 156
  }
157 157

	
158 158
}
159 159

	
160 160
int main() {
161 161

	
162 162
  typedef int Item;
163 163
  typedef int Prio;
164 164
  typedef RangeMap<int> ItemIntMap;
165 165

	
166 166
  Digraph digraph;
167 167
  IntArcMap length(digraph);
168 168
  Node source;
169 169

	
170 170
  std::istringstream input(test_lgf);
171 171
  digraphReader(digraph, input).
172 172
    arcMap("capacity", length).
173 173
    node("source", source).
174 174
    run();
175 175

	
176 176
  // BinHeap
177 177
  {
178 178
    typedef BinHeap<Prio, ItemIntMap> IntHeap;
179 179
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
180 180
    heapSortTest<IntHeap>();
181 181
    heapIncreaseTest<IntHeap>();
182 182

	
183 183
    typedef BinHeap<Prio, IntNodeMap > NodeHeap;
184 184
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
185 185
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
186 186
  }
187 187

	
188
  // FouraryHeap
188
  // QuadHeap
189 189
  {
190
    typedef FouraryHeap<Prio, ItemIntMap> IntHeap;
190
    typedef QuadHeap<Prio, ItemIntMap> IntHeap;
191 191
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
192 192
    heapSortTest<IntHeap>();
193 193
    heapIncreaseTest<IntHeap>();
194 194

	
195
    typedef FouraryHeap<Prio, IntNodeMap > NodeHeap;
195
    typedef QuadHeap<Prio, IntNodeMap > NodeHeap;
196 196
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
197 197
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
198 198
  }
199 199

	
200
  // KaryHeap
200
  // DHeap
201 201
  {
202
    typedef KaryHeap<Prio, ItemIntMap> IntHeap;
202
    typedef DHeap<Prio, ItemIntMap> IntHeap;
203 203
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
204 204
    heapSortTest<IntHeap>();
205 205
    heapIncreaseTest<IntHeap>();
206 206

	
207
    typedef KaryHeap<Prio, IntNodeMap > NodeHeap;
207
    typedef DHeap<Prio, IntNodeMap > NodeHeap;
208 208
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
209 209
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
210 210
  }
211 211

	
212 212
  // FibHeap
213 213
  {
214 214
    typedef FibHeap<Prio, ItemIntMap> IntHeap;
215 215
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
216 216
    heapSortTest<IntHeap>();
217 217
    heapIncreaseTest<IntHeap>();
218 218

	
219 219
    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
220 220
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
221 221
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
222 222
  }
223 223

	
224 224
  // PairingHeap
225 225
  {
226 226
    typedef PairingHeap<Prio, ItemIntMap> IntHeap;
227 227
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
228 228
    heapSortTest<IntHeap>();
229 229
    heapIncreaseTest<IntHeap>();
230 230

	
231 231
    typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
232 232
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
233 233
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
234 234
  }
235 235

	
236 236
  // RadixHeap
237 237
  {
238 238
    typedef RadixHeap<ItemIntMap> IntHeap;
239 239
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
240 240
    heapSortTest<IntHeap>();
241 241
    heapIncreaseTest<IntHeap>();
242 242

	
243 243
    typedef RadixHeap<IntNodeMap > NodeHeap;
244 244
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
245 245
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
246 246
  }
247 247

	
248
  // BinomHeap
248
  // BinomialHeap
249 249
  {
250
    typedef BinomHeap<Prio, ItemIntMap> IntHeap;
250
    typedef BinomialHeap<Prio, ItemIntMap> IntHeap;
251 251
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
252 252
    heapSortTest<IntHeap>();
253 253
    heapIncreaseTest<IntHeap>();
254 254

	
255
    typedef BinomHeap<Prio, IntNodeMap > NodeHeap;
255
    typedef BinomialHeap<Prio, IntNodeMap > NodeHeap;
256 256
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
257 257
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
258 258
  }
259 259

	
260 260
  // BucketHeap, SimpleBucketHeap
261 261
  {
262 262
    typedef BucketHeap<ItemIntMap> IntHeap;
263 263
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
264 264
    heapSortTest<IntHeap>();
265 265
    heapIncreaseTest<IntHeap>();
266 266

	
267 267
    typedef BucketHeap<IntNodeMap > NodeHeap;
268 268
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
269 269
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
270 270

	
271 271
    typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
272 272
    heapSortTest<SimpleIntHeap>();
273 273
  }
274 274

	
275 275
  return 0;
276 276
}
0 comments (0 inline)