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

	
19
#ifndef LEMON_BUCKET_HEAP_H
20
#define LEMON_BUCKET_HEAP_H
21

	
22
///\ingroup auxdat
23
///\file
24
///\brief Bucket Heap implementation.
25

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

	
30
namespace lemon {
31

	
32
  namespace _bucket_heap_bits {
33

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

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

	
54
  }
55

	
56
  /// \ingroup auxdat
57
  ///
58
  /// \brief A Bucket Heap implementation.
59
  ///
60
  /// This class implements the \e bucket \e heap data structure. A \e heap
61
  /// is a data structure for storing items with specified values called \e
62
  /// priorities in such a way that finding the item with minimum priority is
63
  /// efficient. The bucket heap is very simple implementation, it can store
64
  /// only integer priorities and it stores for each priority in the
65
  /// \f$ [0..C) \f$ range a list of items. So it should be used only when
66
  /// the priorities are small. It is not intended to use as dijkstra heap.
67
  ///
68
  /// \param IM A read and write Item int map, used internally
69
  /// to handle the cross references.
70
  /// \param MIN If the given parameter is false then instead of the
71
  /// minimum value the maximum can be retrivied with the top() and
72
  /// prio() member functions.
73
  template <typename IM, bool MIN = true>
74
  class BucketHeap {
75

	
76
  public:
77
    /// \e
78
    typedef typename IM::Key Item;
79
    /// \e
80
    typedef int Prio;
81
    /// \e
82
    typedef std::pair<Item, Prio> Pair;
83
    /// \e
84
    typedef IM ItemIntMap;
85

	
86
  private:
87

	
88
    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
89

	
90
  public:
91

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

	
106
  public:
107
    /// \brief The constructor.
108
    ///
109
    /// The constructor.
110
    /// \param map should be given to the constructor, since it is used
111
    /// internally to handle the cross references. The value of the map
112
    /// should be PRE_HEAP (-1) for each element.
113
    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
114

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

	
120
    /// \brief Checks if the heap stores no items.
121
    ///
122
    /// Returns \c true if and only if the heap stores no items.
123
    bool empty() const { return _data.empty(); }
124

	
125
    /// \brief Make empty this heap.
126
    ///
127
    /// Make empty this heap. It does not change the cross reference
128
    /// map.  If you want to reuse a heap what is not surely empty you
129
    /// should first clear the heap and after that you should set the
130
    /// cross reference map for each item to \c PRE_HEAP.
131
    void clear() {
132
      _data.clear(); _first.clear(); _minimum = 0;
133
    }
134

	
135
  private:
136

	
137
    void relocate_last(int idx) {
138
      if (idx + 1 < int(_data.size())) {
139
        _data[idx] = _data.back();
140
        if (_data[idx].prev != -1) {
141
          _data[_data[idx].prev].next = idx;
142
        } else {
143
          _first[_data[idx].value] = idx;
144
        }
145
        if (_data[idx].next != -1) {
146
          _data[_data[idx].next].prev = idx;
147
        }
148
        _iim[_data[idx].item] = idx;
149
      }
150
      _data.pop_back();
151
    }
152

	
153
    void unlace(int idx) {
154
      if (_data[idx].prev != -1) {
155
        _data[_data[idx].prev].next = _data[idx].next;
156
      } else {
157
        _first[_data[idx].value] = _data[idx].next;
158
      }
159
      if (_data[idx].next != -1) {
160
        _data[_data[idx].next].prev = _data[idx].prev;
161
      }
162
    }
163

	
164
    void lace(int idx) {
165
      if (int(_first.size()) <= _data[idx].value) {
166
        _first.resize(_data[idx].value + 1, -1);
167
      }
168
      _data[idx].next = _first[_data[idx].value];
169
      if (_data[idx].next != -1) {
170
        _data[_data[idx].next].prev = idx;
171
      }
172
      _first[_data[idx].value] = idx;
173
      _data[idx].prev = -1;
174
    }
175

	
176
  public:
177
    /// \brief Insert a pair of item and priority into the heap.
178
    ///
179
    /// Adds \c p.first to the heap with priority \c p.second.
180
    /// \param p The pair to insert.
181
    void push(const Pair& p) {
182
      push(p.first, p.second);
183
    }
184

	
185
    /// \brief Insert an item into the heap with the given priority.
186
    ///
187
    /// Adds \c i to the heap with priority \c p.
188
    /// \param i The item to insert.
189
    /// \param p The priority of the item.
190
    void push(const Item &i, const Prio &p) {
191
      int idx = _data.size();
192
      _iim[i] = idx;
193
      _data.push_back(BucketItem(i, p));
194
      lace(idx);
195
      if (Direction::less(p, _minimum)) {
196
        _minimum = p;
197
      }
198
    }
199

	
200
    /// \brief Returns the item with minimum priority.
201
    ///
202
    /// This method returns the item with minimum priority.
203
    /// \pre The heap must be nonempty.
204
    Item top() const {
205
      while (_first[_minimum] == -1) {
206
        Direction::increase(_minimum);
207
      }
208
      return _data[_first[_minimum]].item;
209
    }
210

	
211
    /// \brief Returns the minimum priority.
212
    ///
213
    /// It returns the minimum priority.
214
    /// \pre The heap must be nonempty.
215
    Prio prio() const {
216
      while (_first[_minimum] == -1) {
217
        Direction::increase(_minimum);
218
      }
219
      return _minimum;
220
    }
221

	
222
    /// \brief Deletes the item with minimum priority.
223
    ///
224
    /// This method deletes the item with minimum priority from the heap.
225
    /// \pre The heap must be non-empty.
226
    void pop() {
227
      while (_first[_minimum] == -1) {
228
        Direction::increase(_minimum);
229
      }
230
      int idx = _first[_minimum];
231
      _iim[_data[idx].item] = -2;
232
      unlace(idx);
233
      relocate_last(idx);
234
    }
235

	
236
    /// \brief Deletes \c i from the heap.
237
    ///
238
    /// This method deletes item \c i from the heap, if \c i was
239
    /// already stored in the heap.
240
    /// \param i The item to erase.
241
    void erase(const Item &i) {
242
      int idx = _iim[i];
243
      _iim[_data[idx].item] = -2;
244
      unlace(idx);
245
      relocate_last(idx);
246
    }
247

	
248

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

	
259
    /// \brief \c i gets to the heap with priority \c p independently
260
    /// if \c i was already there.
261
    ///
262
    /// This method calls \ref push(\c i, \c p) if \c i is not stored
263
    /// in the heap and sets the priority of \c i to \c p otherwise.
264
    /// \param i The item.
265
    /// \param p The priority.
266
    void set(const Item &i, const Prio &p) {
267
      int idx = _iim[i];
268
      if (idx < 0) {
269
        push(i, p);
270
      } else if (Direction::less(p, _data[idx].value)) {
271
        decrease(i, p);
272
      } else {
273
        increase(i, p);
274
      }
275
    }
276

	
277
    /// \brief Decreases the priority of \c i to \c p.
278
    ///
279
    /// This method decreases the priority of item \c i to \c p.
280
    /// \pre \c i must be stored in the heap with priority at least \c
281
    /// p relative to \c Compare.
282
    /// \param i The item.
283
    /// \param p The priority.
284
    void decrease(const Item &i, const Prio &p) {
285
      int idx = _iim[i];
286
      unlace(idx);
287
      _data[idx].value = p;
288
      if (Direction::less(p, _minimum)) {
289
        _minimum = p;
290
      }
291
      lace(idx);
292
    }
293

	
294
    /// \brief Increases the priority of \c i to \c p.
295
    ///
296
    /// This method sets the priority of item \c i to \c p.
297
    /// \pre \c i must be stored in the heap with priority at most \c
298
    /// p relative to \c Compare.
299
    /// \param i The item.
300
    /// \param p The priority.
301
    void increase(const Item &i, const Prio &p) {
302
      int idx = _iim[i];
303
      unlace(idx);
304
      _data[idx].value = p;
305
      lace(idx);
306
    }
307

	
308
    /// \brief Returns if \c item is in, has already been in, or has
309
    /// never been in the heap.
310
    ///
311
    /// This method returns PRE_HEAP if \c item has never been in the
312
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
313
    /// otherwise. In the latter case it is possible that \c item will
314
    /// get back to the heap again.
315
    /// \param i The item.
316
    State state(const Item &i) const {
317
      int idx = _iim[i];
318
      if (idx >= 0) idx = 0;
319
      return State(idx);
320
    }
321

	
322
    /// \brief Sets the state of the \c item in the heap.
323
    ///
324
    /// Sets the state of the \c item in the heap. It can be used to
325
    /// manually clear the heap when it is important to achive the
326
    /// better time complexity.
327
    /// \param i The item.
328
    /// \param st The state. It should not be \c IN_HEAP.
329
    void state(const Item& i, State st) {
330
      switch (st) {
331
      case POST_HEAP:
332
      case PRE_HEAP:
333
        if (state(i) == IN_HEAP) {
334
          erase(i);
335
        }
336
        _iim[i] = st;
337
        break;
338
      case IN_HEAP:
339
        break;
340
      }
341
    }
342

	
343
  private:
344

	
345
    struct BucketItem {
346
      BucketItem(const Item& _item, int _value)
347
        : item(_item), value(_value) {}
348

	
349
      Item item;
350
      int value;
351

	
352
      int prev, next;
353
    };
354

	
355
    ItemIntMap& _iim;
356
    std::vector<int> _first;
357
    std::vector<BucketItem> _data;
358
    mutable int _minimum;
359

	
360
  }; // class BucketHeap
361

	
362
  /// \ingroup auxdat
363
  ///
364
  /// \brief A Simplified Bucket Heap implementation.
365
  ///
366
  /// This class implements a simplified \e bucket \e heap data
367
  /// structure.  It does not provide some functionality but it faster
368
  /// and simplier data structure than the BucketHeap. The main
369
  /// difference is that the BucketHeap stores for every key a double
370
  /// linked list while this class stores just simple lists. In the
371
  /// other way it does not support erasing each elements just the
372
  /// minimal and it does not supports key increasing, decreasing.
373
  ///
374
  /// \param IM A read and write Item int map, used internally
375
  /// to handle the cross references.
376
  /// \param MIN If the given parameter is false then instead of the
377
  /// minimum value the maximum can be retrivied with the top() and
378
  /// prio() member functions.
379
  ///
380
  /// \sa BucketHeap
381
  template <typename IM, bool MIN = true >
382
  class SimpleBucketHeap {
383

	
384
  public:
385
    typedef typename IM::Key Item;
386
    typedef int Prio;
387
    typedef std::pair<Item, Prio> Pair;
388
    typedef IM ItemIntMap;
389

	
390
  private:
391

	
392
    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
393

	
394
  public:
395

	
396
    /// \brief Type to represent the items states.
397
    ///
398
    /// Each Item element have a state associated to it. It may be "in heap",
399
    /// "pre heap" or "post heap". The latter two are indifferent from the
400
    /// heap's point of view, but may be useful to the user.
401
    ///
402
    /// The item-int map must be initialized in such way that it assigns
403
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
404
    enum State {
405
      IN_HEAP = 0,    ///< = 0.
406
      PRE_HEAP = -1,  ///< = -1.
407
      POST_HEAP = -2  ///< = -2.
408
    };
409

	
410
  public:
411

	
412
    /// \brief The constructor.
413
    ///
414
    /// The constructor.
415
    /// \param map should be given to the constructor, since it is used
416
    /// internally to handle the cross references. The value of the map
417
    /// should be PRE_HEAP (-1) for each element.
418
    explicit SimpleBucketHeap(ItemIntMap &map)
419
      : _iim(map), _free(-1), _num(0), _minimum(0) {}
420

	
421
    /// \brief Returns the number of items stored in the heap.
422
    ///
423
    /// The number of items stored in the heap.
424
    int size() const { return _num; }
425

	
426
    /// \brief Checks if the heap stores no items.
427
    ///
428
    /// Returns \c true if and only if the heap stores no items.
429
    bool empty() const { return _num == 0; }
430

	
431
    /// \brief Make empty this heap.
432
    ///
433
    /// Make empty this heap. It does not change the cross reference
434
    /// map.  If you want to reuse a heap what is not surely empty you
435
    /// should first clear the heap and after that you should set the
436
    /// cross reference map for each item to \c PRE_HEAP.
437
    void clear() {
438
      _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
439
    }
440

	
441
    /// \brief Insert a pair of item and priority into the heap.
442
    ///
443
    /// Adds \c p.first to the heap with priority \c p.second.
444
    /// \param p The pair to insert.
445
    void push(const Pair& p) {
446
      push(p.first, p.second);
447
    }
448

	
449
    /// \brief Insert an item into the heap with the given priority.
450
    ///
451
    /// Adds \c i to the heap with priority \c p.
452
    /// \param i The item to insert.
453
    /// \param p The priority of the item.
454
    void push(const Item &i, const Prio &p) {
455
      int idx;
456
      if (_free == -1) {
457
        idx = _data.size();
458
        _data.push_back(BucketItem(i));
459
      } else {
460
        idx = _free;
461
        _free = _data[idx].next;
462
        _data[idx].item = i;
463
      }
464
      _iim[i] = idx;
465
      if (p >= int(_first.size())) _first.resize(p + 1, -1);
466
      _data[idx].next = _first[p];
467
      _first[p] = idx;
468
      if (Direction::less(p, _minimum)) {
469
        _minimum = p;
470
      }
471
      ++_num;
472
    }
473

	
474
    /// \brief Returns the item with minimum priority.
475
    ///
476
    /// This method returns the item with minimum priority.
477
    /// \pre The heap must be nonempty.
478
    Item top() const {
479
      while (_first[_minimum] == -1) {
480
        Direction::increase(_minimum);
481
      }
482
      return _data[_first[_minimum]].item;
483
    }
484

	
485
    /// \brief Returns the minimum priority.
486
    ///
487
    /// It returns the minimum priority.
488
    /// \pre The heap must be nonempty.
489
    Prio prio() const {
490
      while (_first[_minimum] == -1) {
491
        Direction::increase(_minimum);
492
      }
493
      return _minimum;
494
    }
495

	
496
    /// \brief Deletes the item with minimum priority.
497
    ///
498
    /// This method deletes the item with minimum priority from the heap.
499
    /// \pre The heap must be non-empty.
500
    void pop() {
501
      while (_first[_minimum] == -1) {
502
        Direction::increase(_minimum);
503
      }
504
      int idx = _first[_minimum];
505
      _iim[_data[idx].item] = -2;
506
      _first[_minimum] = _data[idx].next;
507
      _data[idx].next = _free;
508
      _free = idx;
509
      --_num;
510
    }
511

	
512
    /// \brief Returns the priority of \c i.
513
    ///
514
    /// This function returns the priority of item \c i.
515
    /// \warning This operator is not a constant time function
516
    /// because it scans the whole data structure to find the proper
517
    /// value.
518
    /// \pre \c i must be in the heap.
519
    /// \param i The item.
520
    Prio operator[](const Item &i) const {
521
      for (int k = 0; k < _first.size(); ++k) {
522
        int idx = _first[k];
523
        while (idx != -1) {
524
          if (_data[idx].item == i) {
525
            return k;
526
          }
527
          idx = _data[idx].next;
528
        }
529
      }
530
      return -1;
531
    }
532

	
533
    /// \brief Returns if \c item is in, has already been in, or has
534
    /// never been in the heap.
535
    ///
536
    /// This method returns PRE_HEAP if \c item has never been in the
537
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
538
    /// otherwise. In the latter case it is possible that \c item will
539
    /// get back to the heap again.
540
    /// \param i The item.
541
    State state(const Item &i) const {
542
      int idx = _iim[i];
543
      if (idx >= 0) idx = 0;
544
      return State(idx);
545
    }
546

	
547
  private:
548

	
549
    struct BucketItem {
550
      BucketItem(const Item& _item)
551
        : item(_item) {}
552

	
553
      Item item;
554
      int next;
555
    };
556

	
557
    ItemIntMap& _iim;
558
    std::vector<int> _first;
559
    std::vector<BucketItem> _data;
560
    int _free, _num;
561
    mutable int _minimum;
562

	
563
  }; // class SimpleBucketHeap
564

	
565
}
566

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

	
19
#ifndef LEMON_FIB_HEAP_H
20
#define LEMON_FIB_HEAP_H
21

	
22
///\file
23
///\ingroup auxdat
24
///\brief Fibonacci Heap implementation.
25

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

	
30
namespace lemon {
31

	
32
  /// \ingroup auxdat
33
  ///
34
  ///\brief Fibonacci Heap.
35
  ///
36
  ///This class implements the \e Fibonacci \e heap data structure. A \e heap
37
  ///is a data structure for storing items with specified values called \e
38
  ///priorities in such a way that finding the item with minimum priority is
39
  ///efficient. \c CMP specifies the ordering of the priorities. In a heap
40
  ///one can change the priority of an item, add or erase an item, etc.
41
  ///
42
  ///The methods \ref increase and \ref erase are not efficient in a Fibonacci
43
  ///heap. In case of many calls to these operations, it is better to use a
44
  ///\ref BinHeap "binary heap".
45
  ///
46
  ///\param PRIO Type of the priority of the items.
47
  ///\param IM A read and writable Item int map, used internally
48
  ///to handle the cross references.
49
  ///\param CMP A class for the ordering of the priorities. The
50
  ///default is \c std::less<PRIO>.
51
  ///
52
  ///\sa BinHeap
53
  ///\sa Dijkstra
54
#ifdef DOXYGEN
55
  template <typename PRIO, typename IM, typename CMP>
56
#else
57
  template <typename PRIO, typename IM, typename CMP = std::less<PRIO> >
58
#endif
59
  class FibHeap {
60
  public:
61
    ///\e
62
    typedef IM ItemIntMap;
63
    ///\e
64
    typedef PRIO Prio;
65
    ///\e
66
    typedef typename ItemIntMap::Key Item;
67
    ///\e
68
    typedef std::pair<Item,Prio> Pair;
69
    ///\e
70
    typedef CMP Compare;
71

	
72
  private:
73
    class Store;
74

	
75
    std::vector<Store> _data;
76
    int _minimum;
77
    ItemIntMap &_iim;
78
    Compare _comp;
79
    int _num;
80

	
81
  public:
82

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

	
97
    /// \brief The constructor
98
    ///
99
    /// \c map should be given to the constructor, since it is
100
    ///   used internally to handle the cross references.
101
    explicit FibHeap(ItemIntMap &map)
102
      : _minimum(0), _iim(map), _num() {}
103

	
104
    /// \brief The constructor
105
    ///
106
    /// \c map should be given to the constructor, since it is used
107
    /// internally to handle the cross references. \c comp is an
108
    /// object for ordering of the priorities.
109
    FibHeap(ItemIntMap &map, const Compare &comp)
110
      : _minimum(0), _iim(map), _comp(comp), _num() {}
111

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

	
117
    /// \brief Checks if the heap stores no items.
118
    ///
119
    ///   Returns \c true if and only if the heap stores no items.
120
    bool empty() const { return _num==0; }
121

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

	
132
    /// \brief \c item gets to the heap with priority \c value independently
133
    /// if \c item was already there.
134
    ///
135
    /// This method calls \ref push(\c item, \c value) if \c item is not
136
    /// stored in the heap and it calls \ref decrease(\c item, \c value) or
137
    /// \ref increase(\c item, \c value) otherwise.
138
    void set (const Item& item, const Prio& value) {
139
      int i=_iim[item];
140
      if ( i >= 0 && _data[i].in ) {
141
        if ( _comp(value, _data[i].prio) ) decrease(item, value);
142
        if ( _comp(_data[i].prio, value) ) increase(item, value);
143
      } else push(item, value);
144
    }
145

	
146
    /// \brief Adds \c item to the heap with priority \c value.
147
    ///
148
    /// Adds \c item to the heap with priority \c value.
149
    /// \pre \c item must not be stored in the heap.
150
    void push (const Item& item, const Prio& value) {
151
      int i=_iim[item];
152
      if ( i < 0 ) {
153
        int s=_data.size();
154
        _iim.set( item, s );
155
        Store st;
156
        st.name=item;
157
        _data.push_back(st);
158
        i=s;
159
      } else {
160
        _data[i].parent=_data[i].child=-1;
161
        _data[i].degree=0;
162
        _data[i].in=true;
163
        _data[i].marked=false;
164
      }
165

	
166
      if ( _num ) {
167
        _data[_data[_minimum].right_neighbor].left_neighbor=i;
168
        _data[i].right_neighbor=_data[_minimum].right_neighbor;
169
        _data[_minimum].right_neighbor=i;
170
        _data[i].left_neighbor=_minimum;
171
        if ( _comp( value, _data[_minimum].prio) ) _minimum=i;
172
      } else {
173
        _data[i].right_neighbor=_data[i].left_neighbor=i;
174
        _minimum=i;
175
      }
176
      _data[i].prio=value;
177
      ++_num;
178
    }
179

	
180
    /// \brief Returns the item with minimum priority relative to \c Compare.
181
    ///
182
    /// This method returns the item with minimum priority relative to \c
183
    /// Compare.
184
    /// \pre The heap must be nonempty.
185
    Item top() const { return _data[_minimum].name; }
186

	
187
    /// \brief Returns the minimum priority relative to \c Compare.
188
    ///
189
    /// It returns the minimum priority relative to \c Compare.
190
    /// \pre The heap must be nonempty.
191
    const Prio& prio() const { return _data[_minimum].prio; }
192

	
193
    /// \brief Returns the priority of \c item.
194
    ///
195
    /// It returns the priority of \c item.
196
    /// \pre \c item must be in the heap.
197
    const Prio& operator[](const Item& item) const {
198
      return _data[_iim[item]].prio;
199
    }
200

	
201
    /// \brief Deletes the item with minimum priority relative to \c Compare.
202
    ///
203
    /// This method deletes the item with minimum priority relative to \c
204
    /// Compare from the heap.
205
    /// \pre The heap must be non-empty.
206
    void pop() {
207
      /*The first case is that there are only one root.*/
208
      if ( _data[_minimum].left_neighbor==_minimum ) {
209
        _data[_minimum].in=false;
210
        if ( _data[_minimum].degree!=0 ) {
211
          makeroot(_data[_minimum].child);
212
          _minimum=_data[_minimum].child;
213
          balance();
214
        }
215
      } else {
216
        int right=_data[_minimum].right_neighbor;
217
        unlace(_minimum);
218
        _data[_minimum].in=false;
219
        if ( _data[_minimum].degree > 0 ) {
220
          int left=_data[_minimum].left_neighbor;
221
          int child=_data[_minimum].child;
222
          int last_child=_data[child].left_neighbor;
223

	
224
          makeroot(child);
225

	
226
          _data[left].right_neighbor=child;
227
          _data[child].left_neighbor=left;
228
          _data[right].left_neighbor=last_child;
229
          _data[last_child].right_neighbor=right;
230
        }
231
        _minimum=right;
232
        balance();
233
      } // the case where there are more roots
234
      --_num;
235
    }
236

	
237
    /// \brief Deletes \c item from the heap.
238
    ///
239
    /// This method deletes \c item from the heap, if \c item was already
240
    /// stored in the heap. It is quite inefficient in Fibonacci heaps.
241
    void erase (const Item& item) {
242
      int i=_iim[item];
243

	
244
      if ( i >= 0 && _data[i].in ) {
245
        if ( _data[i].parent!=-1 ) {
246
          int p=_data[i].parent;
247
          cut(i,p);
248
          cascade(p);
249
        }
250
        _minimum=i;     //As if its prio would be -infinity
251
        pop();
252
      }
253
    }
254

	
255
    /// \brief Decreases the priority of \c item to \c value.
256
    ///
257
    /// This method decreases the priority of \c item to \c value.
258
    /// \pre \c item must be stored in the heap with priority at least \c
259
    ///   value relative to \c Compare.
260
    void decrease (Item item, const Prio& value) {
261
      int i=_iim[item];
262
      _data[i].prio=value;
263
      int p=_data[i].parent;
264

	
265
      if ( p!=-1 && _comp(value, _data[p].prio) ) {
266
        cut(i,p);
267
        cascade(p);
268
      }
269
      if ( _comp(value, _data[_minimum].prio) ) _minimum=i;
270
    }
271

	
272
    /// \brief Increases the priority of \c item to \c value.
273
    ///
274
    /// This method sets the priority of \c item to \c value. Though
275
    /// there is no precondition on the priority of \c item, this
276
    /// method should be used only if it is indeed necessary to increase
277
    /// (relative to \c Compare) the priority of \c item, because this
278
    /// method is inefficient.
279
    void increase (Item item, const Prio& value) {
280
      erase(item);
281
      push(item, value);
282
    }
283

	
284

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

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

	
322
  private:
323

	
324
    void balance() {
325

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

	
328
      std::vector<int> A(maxdeg,-1);
329

	
330
      /*
331
       *Recall that now minimum does not point to the minimum prio element.
332
       *We set minimum to this during balance().
333
       */
334
      int anchor=_data[_minimum].left_neighbor;
335
      int next=_minimum;
336
      bool end=false;
337

	
338
      do {
339
        int active=next;
340
        if ( anchor==active ) end=true;
341
        int d=_data[active].degree;
342
        next=_data[active].right_neighbor;
343

	
344
        while (A[d]!=-1) {
345
          if( _comp(_data[active].prio, _data[A[d]].prio) ) {
346
            fuse(active,A[d]);
347
          } else {
348
            fuse(A[d],active);
349
            active=A[d];
350
          }
351
          A[d]=-1;
352
          ++d;
353
        }
354
        A[d]=active;
355
      } while ( !end );
356

	
357

	
358
      while ( _data[_minimum].parent >=0 )
359
        _minimum=_data[_minimum].parent;
360
      int s=_minimum;
361
      int m=_minimum;
362
      do {
363
        if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
364
        s=_data[s].right_neighbor;
365
      } while ( s != m );
366
    }
367

	
368
    void makeroot(int c) {
369
      int s=c;
370
      do {
371
        _data[s].parent=-1;
372
        s=_data[s].right_neighbor;
373
      } while ( s != c );
374
    }
375

	
376
    void cut(int a, int b) {
377
      /*
378
       *Replacing a from the children of b.
379
       */
380
      --_data[b].degree;
381

	
382
      if ( _data[b].degree !=0 ) {
383
        int child=_data[b].child;
384
        if ( child==a )
385
          _data[b].child=_data[child].right_neighbor;
386
        unlace(a);
387
      }
388

	
389

	
390
      /*Lacing a to the roots.*/
391
      int right=_data[_minimum].right_neighbor;
392
      _data[_minimum].right_neighbor=a;
393
      _data[a].left_neighbor=_minimum;
394
      _data[a].right_neighbor=right;
395
      _data[right].left_neighbor=a;
396

	
397
      _data[a].parent=-1;
398
      _data[a].marked=false;
399
    }
400

	
401
    void cascade(int a) {
402
      if ( _data[a].parent!=-1 ) {
403
        int p=_data[a].parent;
404

	
405
        if ( _data[a].marked==false ) _data[a].marked=true;
406
        else {
407
          cut(a,p);
408
          cascade(p);
409
        }
410
      }
411
    }
412

	
413
    void fuse(int a, int b) {
414
      unlace(b);
415

	
416
      /*Lacing b under a.*/
417
      _data[b].parent=a;
418

	
419
      if (_data[a].degree==0) {
420
        _data[b].left_neighbor=b;
421
        _data[b].right_neighbor=b;
422
        _data[a].child=b;
423
      } else {
424
        int child=_data[a].child;
425
        int last_child=_data[child].left_neighbor;
426
        _data[child].left_neighbor=b;
427
        _data[b].right_neighbor=child;
428
        _data[last_child].right_neighbor=b;
429
        _data[b].left_neighbor=last_child;
430
      }
431

	
432
      ++_data[a].degree;
433

	
434
      _data[b].marked=false;
435
    }
436

	
437
    /*
438
     *It is invoked only if a has siblings.
439
     */
440
    void unlace(int a) {
441
      int leftn=_data[a].left_neighbor;
442
      int rightn=_data[a].right_neighbor;
443
      _data[leftn].right_neighbor=rightn;
444
      _data[rightn].left_neighbor=leftn;
445
    }
446

	
447

	
448
    class Store {
449
      friend class FibHeap;
450

	
451
      Item name;
452
      int parent;
453
      int left_neighbor;
454
      int right_neighbor;
455
      int child;
456
      int degree;
457
      bool marked;
458
      bool in;
459
      Prio prio;
460

	
461
      Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
462
    };
463
  };
464

	
465
} //namespace lemon
466

	
467
#endif //LEMON_FIB_HEAP_H
468

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

	
19
#ifndef LEMON_RADIX_HEAP_H
20
#define LEMON_RADIX_HEAP_H
21

	
22
///\ingroup auxdat
23
///\file
24
///\brief Radix Heap implementation.
25

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

	
29
namespace lemon {
30

	
31

	
32
  /// \ingroup auxdata
33
  ///
34
  /// \brief A Radix Heap implementation.
35
  ///
36
  /// This class implements the \e radix \e heap data structure. A \e heap
37
  /// is a data structure for storing items with specified values called \e
38
  /// priorities in such a way that finding the item with minimum priority is
39
  /// efficient. This heap type can store only items with \e int priority.
40
  /// In a heap one can change the priority of an item, add or erase an
41
  /// item, but the priority cannot be decreased under the last removed
42
  /// item's priority.
43
  ///
44
  /// \param IM A read and writable Item int map, used internally
45
  /// to handle the cross references.
46
  ///
47
  /// \see BinHeap
48
  /// \see Dijkstra
49
  template <typename IM>
50
  class RadixHeap {
51

	
52
  public:
53
    typedef typename IM::Key Item;
54
    typedef int Prio;
55
    typedef IM ItemIntMap;
56

	
57
    /// \brief Exception thrown by RadixHeap.
58
    ///
59
    /// This Exception is thrown when a smaller priority
60
    /// is inserted into the \e RadixHeap then the last time erased.
61
    /// \see RadixHeap
62

	
63
    class UnderFlowPriorityError : public Exception {
64
    public:
65
      virtual const char* what() const throw() {
66
        return "lemon::RadixHeap::UnderFlowPriorityError";
67
      }
68
    };
69

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

	
84
  private:
85

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

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

	
99
    std::vector<RadixItem> data;
100
    std::vector<RadixBox> boxes;
101

	
102
    ItemIntMap &_iim;
103

	
104

	
105
  public:
106
    /// \brief The constructor.
107
    ///
108
    /// The constructor.
109
    ///
110
    /// \param map It should be given to the constructor, since it is used
111
    /// internally to handle the cross references. The value of the map
112
    /// should be PRE_HEAP (-1) for each element.
113
    ///
114
    /// \param minimal The initial minimal value of the heap.
115
    /// \param capacity It determines the initial capacity of the heap.
116
    RadixHeap(ItemIntMap &map, int minimal = 0, int capacity = 0)
117
      : _iim(map) {
118
      boxes.push_back(RadixBox(minimal, 1));
119
      boxes.push_back(RadixBox(minimal + 1, 1));
120
      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
121
        extend();
122
      }
123
    }
124

	
125
    /// The number of items stored in the heap.
126
    ///
127
    /// \brief Returns the number of items stored in the heap.
128
    int size() const { return data.size(); }
129
    /// \brief Checks if the heap stores no items.
130
    ///
131
    /// Returns \c true if and only if the heap stores no items.
132
    bool empty() const { return data.empty(); }
133

	
134
    /// \brief Make empty this heap.
135
    ///
136
    /// Make empty this heap. It does not change the cross reference
137
    /// map.  If you want to reuse a heap what is not surely empty you
138
    /// should first clear the heap and after that you should set the
139
    /// cross reference map for each item to \c PRE_HEAP.
140
    void clear(int minimal = 0, int capacity = 0) {
141
      data.clear(); boxes.clear();
142
      boxes.push_back(RadixBox(minimal, 1));
143
      boxes.push_back(RadixBox(minimal + 1, 1));
144
      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
145
        extend();
146
      }
147
    }
148

	
149
  private:
150

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

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

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

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

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

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

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

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

	
218
    /// \brief Find up the proper box for the item with the given prio.
219
    int findDown(int start, int pr) {
220
      while (upper(start, pr)) {
221
        if (--start < 0) throw UnderFlowPriorityError();
222
      }
223
      return start;
224
    }
225

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

	
233
    /// \brief Gives back the minimal prio of the box.
234
    int minValue(int box) {
235
      int min = data[boxes[box].first].prio;
236
      for (int k = boxes[box].first; k != -1; k = data[k].next) {
237
        if (data[k].prio < min) min = data[k].prio;
238
      }
239
      return min;
240
    }
241

	
242
    /// \brief Rearrange the items of the heap and makes the
243
    /// first box not empty.
244
    void moveDown() {
245
      int box = findFirst();
246
      if (box == 0) return;
247
      int min = minValue(box);
248
      for (int i = 0; i <= box; ++i) {
249
        boxes[i].min = min;
250
        min += boxes[i].size;
251
      }
252
      int curr = boxes[box].first, next;
253
      while (curr != -1) {
254
        next = data[curr].next;
255
        bubble_down(curr);
256
        curr = next;
257
      }
258
    }
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;
265
        } else {
266
          boxes[data[index].box].first = index;
267
        }
268
        if (data[index].next != -1) {
269
          data[data[index].next].prev = index;
270
        }
271
        _iim[data[index].item] = index;
272
      }
273
      data.pop_back();
274
    }
275

	
276
  public:
277

	
278
    /// \brief Insert an item into the heap with the given priority.
279
    ///
280
    /// Adds \c i to the heap with priority \c p.
281
    /// \param i The item to insert.
282
    /// \param p The priority of the item.
283
    void push(const Item &i, const Prio &p) {
284
      int n = data.size();
285
      _iim.set(i, n);
286
      data.push_back(RadixItem(i, p));
287
      while (lower(boxes.size() - 1, p)) {
288
        extend();
289
      }
290
      int box = findDown(boxes.size() - 1, p);
291
      insert(box, n);
292
    }
293

	
294
    /// \brief Returns the item with minimum priority.
295
    ///
296
    /// This method returns the item with minimum priority.
297
    /// \pre The heap must be nonempty.
298
    Item top() const {
299
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
300
      return data[boxes[0].first].item;
301
    }
302

	
303
    /// \brief Returns the minimum priority.
304
    ///
305
    /// It returns the minimum priority.
306
    /// \pre The heap must be nonempty.
307
    Prio prio() const {
308
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
309
      return data[boxes[0].first].prio;
310
     }
311

	
312
    /// \brief Deletes the item with minimum priority.
313
    ///
314
    /// This method deletes the item with minimum priority.
315
    /// \pre The heap must be non-empty.
316
    void pop() {
317
      moveDown();
318
      int index = boxes[0].first;
319
      _iim[data[index].item] = POST_HEAP;
320
      remove(index);
321
      relocate_last(index);
322
    }
323

	
324
    /// \brief Deletes \c i from the heap.
325
    ///
326
    /// This method deletes item \c i from the heap, if \c i was
327
    /// already stored in the heap.
328
    /// \param i The item to erase.
329
    void erase(const Item &i) {
330
      int index = _iim[i];
331
      _iim[i] = POST_HEAP;
332
      remove(index);
333
      relocate_last(index);
334
   }
335

	
336
    /// \brief Returns the priority of \c i.
337
    ///
338
    /// This function returns the priority of item \c i.
339
    /// \pre \c i must be in the heap.
340
    /// \param i The item.
341
    Prio operator[](const Item &i) const {
342
      int idx = _iim[i];
343
      return data[idx].prio;
344
    }
345

	
346
    /// \brief \c i gets to the heap with priority \c p independently
347
    /// if \c i was already there.
348
    ///
349
    /// This method calls \ref push(\c i, \c p) if \c i is not stored
350
    /// in the heap and sets the priority of \c i to \c p otherwise.
351
    /// It may throw an \e UnderFlowPriorityException.
352
    /// \param i The item.
353
    /// \param p The priority.
354
    void set(const Item &i, const Prio &p) {
355
      int idx = _iim[i];
356
      if( idx < 0 ) {
357
        push(i, p);
358
      }
359
      else if( p >= data[idx].prio ) {
360
        data[idx].prio = p;
361
        bubble_up(idx);
362
      } else {
363
        data[idx].prio = p;
364
        bubble_down(idx);
365
      }
366
    }
367

	
368

	
369
    /// \brief Decreases the priority of \c i to \c p.
370
    ///
371
    /// This method decreases the priority of item \c i to \c p.
372
    /// \pre \c i must be stored in the heap with priority at least \c p, and
373
    /// \c should be greater or equal to the last removed item's priority.
374
    /// \param i The item.
375
    /// \param p The priority.
376
    void decrease(const Item &i, const Prio &p) {
377
      int idx = _iim[i];
378
      data[idx].prio = p;
379
      bubble_down(idx);
380
    }
381

	
382
    /// \brief Increases the priority of \c i to \c p.
383
    ///
384
    /// This method sets the priority of item \c i to \c p.
385
    /// \pre \c i must be stored in the heap with priority at most \c p
386
    /// \param i The item.
387
    /// \param p The priority.
388
    void increase(const Item &i, const Prio &p) {
389
      int idx = _iim[i];
390
      data[idx].prio = p;
391
      bubble_up(idx);
392
    }
393

	
394
    /// \brief Returns if \c item is in, has already been in, or has
395
    /// never been in the heap.
396
    ///
397
    /// This method returns PRE_HEAP if \c item has never been in the
398
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
399
    /// otherwise. In the latter case it is possible that \c item will
400
    /// get back to the heap again.
401
    /// \param i The item.
402
    State state(const Item &i) const {
403
      int s = _iim[i];
404
      if( s >= 0 ) s = 0;
405
      return State(s);
406
    }
407

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

	
429
  }; // class RadixHeap
430

	
431
} // namespace lemon
432

	
433
#endif // LEMON_RADIX_HEAP_H
Ignore white space 6 line context
... ...
@@ -56,12 +56,13 @@
56 56
lemon_HEADERS += \
57 57
	lemon/adaptors.h \
58 58
	lemon/arg_parser.h \
59 59
	lemon/assert.h \
60 60
	lemon/bfs.h \
61 61
	lemon/bin_heap.h \
62
	lemon/bucket_heap.h \
62 63
	lemon/cbc.h \
63 64
	lemon/circulation.h \
64 65
	lemon/clp.h \
65 66
	lemon/color.h \
66 67
	lemon/concept_check.h \
67 68
	lemon/connectivity.h \
... ...
@@ -73,12 +74,13 @@
73 74
	lemon/dim2.h \
74 75
	lemon/dimacs.h \
75 76
	lemon/edge_set.h \
76 77
	lemon/elevator.h \
77 78
	lemon/error.h \
78 79
	lemon/euler.h \
80
	lemon/fib_heap.h \
79 81
	lemon/full_graph.h \
80 82
	lemon/glpk.h \
81 83
	lemon/gomory_hu.h \
82 84
	lemon/graph_to_eps.h \
83 85
	lemon/grid_graph.h \
84 86
	lemon/hypercube_graph.h \
... ...
@@ -96,12 +98,13 @@
96 98
	lemon/math.h \
97 99
	lemon/min_cost_arborescence.h \
98 100
	lemon/nauty_reader.h \
99 101
	lemon/network_simplex.h \
100 102
	lemon/path.h \
101 103
	lemon/preflow.h \
104
	lemon/radix_heap.h \
102 105
	lemon/radix_sort.h \
103 106
	lemon/random.h \
104 107
	lemon/smart_graph.h \
105 108
	lemon/soplex.h \
106 109
	lemon/suurballe.h \
107 110
	lemon/time_measure.h \
Ignore white space 6 line context
... ...
@@ -30,42 +30,42 @@
30 30
namespace lemon {
31 31

	
32 32
  ///\ingroup auxdat
33 33
  ///
34 34
  ///\brief A Binary Heap implementation.
35 35
  ///
36
  ///This class implements the \e binary \e heap data structure. 
37
  /// 
36
  ///This class implements the \e binary \e heap data structure.
37
  ///
38 38
  ///A \e heap is a data structure for storing items with specified values
39 39
  ///called \e priorities in such a way that finding the item with minimum
40
  ///priority is efficient. \c Comp specifies the ordering of the priorities.
40
  ///priority is efficient. \c CMP specifies the ordering of the priorities.
41 41
  ///In a heap one can change the priority of an item, add or erase an
42 42
  ///item, etc.
43 43
  ///
44 44
  ///\tparam PR Type of the priority of the items.
45 45
  ///\tparam IM A read and writable item map with int values, used internally
46 46
  ///to handle the cross references.
47
  ///\tparam Comp A functor class for the ordering of the priorities.
47
  ///\tparam CMP A functor class for the ordering of the priorities.
48 48
  ///The default is \c std::less<PR>.
49 49
  ///
50 50
  ///\sa FibHeap
51 51
  ///\sa Dijkstra
52
  template <typename PR, typename IM, typename Comp = std::less<PR> >
52
  template <typename PR, typename IM, typename CMP = std::less<PR> >
53 53
  class BinHeap {
54 54

	
55 55
  public:
56 56
    ///\e
57 57
    typedef IM ItemIntMap;
58 58
    ///\e
59 59
    typedef PR Prio;
60 60
    ///\e
61 61
    typedef typename ItemIntMap::Key Item;
62 62
    ///\e
63 63
    typedef std::pair<Item,Prio> Pair;
64 64
    ///\e
65
    typedef Comp Compare;
65
    typedef CMP Compare;
66 66

	
67 67
    /// \brief Type to represent the items states.
68 68
    ///
69 69
    /// Each Item element have a state associated to it. It may 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.
Ignore white space 6 line context
... ...
@@ -19,21 +19,20 @@
19 19
#ifndef LEMON_MAPS_H
20 20
#define LEMON_MAPS_H
21 21

	
22 22
#include <iterator>
23 23
#include <functional>
24 24
#include <vector>
25
#include <map>
25 26

	
26 27
#include <lemon/core.h>
27 28

	
28 29
///\file
29 30
///\ingroup maps
30 31
///\brief Miscellaneous property maps
31 32

	
32
#include <map>
33

	
34 33
namespace lemon {
35 34

	
36 35
  /// \addtogroup maps
37 36
  /// @{
38 37

	
39 38
  /// Base class of maps.
... ...
@@ -1815,13 +1814,13 @@
1815 1814
  /// \addtogroup graph_maps
1816 1815
  /// @{
1817 1816

	
1818 1817
  /// \brief Provides an immutable and unique id for each item in a graph.
1819 1818
  ///
1820 1819
  /// IdMap provides a unique and immutable id for each item of the
1821
  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is 
1820
  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
1822 1821
  ///  - \b unique: different items get different ids,
1823 1822
  ///  - \b immutable: the id of an item does not change (even if you
1824 1823
  ///    delete other nodes).
1825 1824
  ///
1826 1825
  /// Using this map you get access (i.e. can read) the inner id values of
1827 1826
  /// the items stored in the graph, which is returned by the \c id()
... ...
@@ -2278,13 +2277,13 @@
2278 2277
    /// Gives back the \e RangeId of the item.
2279 2278
    int operator[](const Item& item) const {
2280 2279
      return Map::operator[](item);
2281 2280
    }
2282 2281

	
2283 2282
    /// \brief Gives back the item belonging to a \e RangeId
2284
    /// 
2283
    ///
2285 2284
    /// Gives back the item belonging to a \e RangeId.
2286 2285
    Item operator()(int id) const {
2287 2286
      return _inv_map[id];
2288 2287
    }
2289 2288

	
2290 2289
  private:
... ...
@@ -2335,12 +2334,909 @@
2335 2334
    /// Gives back the inverse of the map.
2336 2335
    const InverseMap inverse() const {
2337 2336
      return InverseMap(*this);
2338 2337
    }
2339 2338
  };
2340 2339

	
2340
  /// \brief Dynamic iterable \c bool map.
2341
  ///
2342
  /// This class provides a special graph map type which can store a
2343
  /// \c bool value for graph items (\c Node, \c Arc or \c Edge).
2344
  /// For both \c true and \c false values it is possible to iterate on
2345
  /// the keys.
2346
  ///
2347
  /// This type is a reference map, so it can be modified with the
2348
  /// subscription operator.
2349
  ///
2350
  /// \tparam GR The graph type.
2351
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
2352
  /// \c GR::Edge).
2353
  ///
2354
  /// \see IterableIntMap, IterableValueMap
2355
  /// \see CrossRefMap
2356
  template <typename GR, typename K>
2357
  class IterableBoolMap
2358
    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
2359
  private:
2360
    typedef GR Graph;
2361

	
2362
    typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;
2363
    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;
2364

	
2365
    std::vector<K> _array;
2366
    int _sep;
2367

	
2368
  public:
2369

	
2370
    /// Indicates that the map is reference map.
2371
    typedef True ReferenceMapTag;
2372

	
2373
    /// The key type
2374
    typedef K Key;
2375
    /// The value type
2376
    typedef bool Value;
2377
    /// The const reference type.
2378
    typedef const Value& ConstReference;
2379

	
2380
  private:
2381

	
2382
    int position(const Key& key) const {
2383
      return Parent::operator[](key);
2384
    }
2385

	
2386
  public:
2387

	
2388
    /// \brief Reference to the value of the map.
2389
    ///
2390
    /// This class is similar to the \c bool type. It can be converted to
2391
    /// \c bool and it provides the same operators.
2392
    class Reference {
2393
      friend class IterableBoolMap;
2394
    private:
2395
      Reference(IterableBoolMap& map, const Key& key)
2396
        : _key(key), _map(map) {}
2397
    public:
2398

	
2399
      Reference& operator=(const Reference& value) {
2400
        _map.set(_key, static_cast<bool>(value));
2401
         return *this;
2402
      }
2403

	
2404
      operator bool() const {
2405
        return static_cast<const IterableBoolMap&>(_map)[_key];
2406
      }
2407

	
2408
      Reference& operator=(bool value) {
2409
        _map.set(_key, value);
2410
        return *this;
2411
      }
2412
      Reference& operator&=(bool value) {
2413
        _map.set(_key, _map[_key] & value);
2414
        return *this;
2415
      }
2416
      Reference& operator|=(bool value) {
2417
        _map.set(_key, _map[_key] | value);
2418
        return *this;
2419
      }
2420
      Reference& operator^=(bool value) {
2421
        _map.set(_key, _map[_key] ^ value);
2422
        return *this;
2423
      }
2424
    private:
2425
      Key _key;
2426
      IterableBoolMap& _map;
2427
    };
2428

	
2429
    /// \brief Constructor of the map with a default value.
2430
    ///
2431
    /// Constructor of the map with a default value.
2432
    explicit IterableBoolMap(const Graph& graph, bool def = false)
2433
      : Parent(graph) {
2434
      typename Parent::Notifier* nf = Parent::notifier();
2435
      Key it;
2436
      for (nf->first(it); it != INVALID; nf->next(it)) {
2437
        Parent::set(it, _array.size());
2438
        _array.push_back(it);
2439
      }
2440
      _sep = (def ? _array.size() : 0);
2441
    }
2442

	
2443
    /// \brief Const subscript operator of the map.
2444
    ///
2445
    /// Const subscript operator of the map.
2446
    bool operator[](const Key& key) const {
2447
      return position(key) < _sep;
2448
    }
2449

	
2450
    /// \brief Subscript operator of the map.
2451
    ///
2452
    /// Subscript operator of the map.
2453
    Reference operator[](const Key& key) {
2454
      return Reference(*this, key);
2455
    }
2456

	
2457
    /// \brief Set operation of the map.
2458
    ///
2459
    /// Set operation of the map.
2460
    void set(const Key& key, bool value) {
2461
      int pos = position(key);
2462
      if (value) {
2463
        if (pos < _sep) return;
2464
        Key tmp = _array[_sep];
2465
        _array[_sep] = key;
2466
        Parent::set(key, _sep);
2467
        _array[pos] = tmp;
2468
        Parent::set(tmp, pos);
2469
        ++_sep;
2470
      } else {
2471
        if (pos >= _sep) return;
2472
        --_sep;
2473
        Key tmp = _array[_sep];
2474
        _array[_sep] = key;
2475
        Parent::set(key, _sep);
2476
        _array[pos] = tmp;
2477
        Parent::set(tmp, pos);
2478
      }
2479
    }
2480

	
2481
    /// \brief Set all items.
2482
    ///
2483
    /// Set all items in the map.
2484
    /// \note Constant time operation.
2485
    void setAll(bool value) {
2486
      _sep = (value ? _array.size() : 0);
2487
    }
2488

	
2489
    /// \brief Returns the number of the keys mapped to \c true.
2490
    ///
2491
    /// Returns the number of the keys mapped to \c true.
2492
    int trueNum() const {
2493
      return _sep;
2494
    }
2495

	
2496
    /// \brief Returns the number of the keys mapped to \c false.
2497
    ///
2498
    /// Returns the number of the keys mapped to \c false.
2499
    int falseNum() const {
2500
      return _array.size() - _sep;
2501
    }
2502

	
2503
    /// \brief Iterator for the keys mapped to \c true.
2504
    ///
2505
    /// Iterator for the keys mapped to \c true. It works
2506
    /// like a graph item iterator, it can be converted to
2507
    /// the key type of the map, incremented with \c ++ operator, and
2508
    /// if the iterator leaves the last valid key, it will be equal to
2509
    /// \c INVALID.
2510
    class TrueIt : public Key {
2511
    public:
2512
      typedef Key Parent;
2513

	
2514
      /// \brief Creates an iterator.
2515
      ///
2516
      /// Creates an iterator. It iterates on the
2517
      /// keys mapped to \c true.
2518
      /// \param map The IterableBoolMap.
2519
      explicit TrueIt(const IterableBoolMap& map)
2520
        : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
2521
          _map(&map) {}
2522

	
2523
      /// \brief Invalid constructor \& conversion.
2524
      ///
2525
      /// This constructor initializes the iterator to be invalid.
2526
      /// \sa Invalid for more details.
2527
      TrueIt(Invalid) : Parent(INVALID), _map(0) {}
2528

	
2529
      /// \brief Increment operator.
2530
      ///
2531
      /// Increment operator.
2532
      TrueIt& operator++() {
2533
        int pos = _map->position(*this);
2534
        Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
2535
        return *this;
2536
      }
2537

	
2538
    private:
2539
      const IterableBoolMap* _map;
2540
    };
2541

	
2542
    /// \brief Iterator for the keys mapped to \c false.
2543
    ///
2544
    /// Iterator for the keys mapped to \c false. It works
2545
    /// like a graph item iterator, it can be converted to
2546
    /// the key type of the map, incremented with \c ++ operator, and
2547
    /// if the iterator leaves the last valid key, it will be equal to
2548
    /// \c INVALID.
2549
    class FalseIt : public Key {
2550
    public:
2551
      typedef Key Parent;
2552

	
2553
      /// \brief Creates an iterator.
2554
      ///
2555
      /// Creates an iterator. It iterates on the
2556
      /// keys mapped to \c false.
2557
      /// \param map The IterableBoolMap.
2558
      explicit FalseIt(const IterableBoolMap& map)
2559
        : Parent(map._sep < int(map._array.size()) ?
2560
                 map._array.back() : INVALID), _map(&map) {}
2561

	
2562
      /// \brief Invalid constructor \& conversion.
2563
      ///
2564
      /// This constructor initializes the iterator to be invalid.
2565
      /// \sa Invalid for more details.
2566
      FalseIt(Invalid) : Parent(INVALID), _map(0) {}
2567

	
2568
      /// \brief Increment operator.
2569
      ///
2570
      /// Increment operator.
2571
      FalseIt& operator++() {
2572
        int pos = _map->position(*this);
2573
        Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
2574
        return *this;
2575
      }
2576

	
2577
    private:
2578
      const IterableBoolMap* _map;
2579
    };
2580

	
2581
    /// \brief Iterator for the keys mapped to a given value.
2582
    ///
2583
    /// Iterator for the keys mapped to a given value. It works
2584
    /// like a graph item iterator, it can be converted to
2585
    /// the key type of the map, incremented with \c ++ operator, and
2586
    /// if the iterator leaves the last valid key, it will be equal to
2587
    /// \c INVALID.
2588
    class ItemIt : public Key {
2589
    public:
2590
      typedef Key Parent;
2591

	
2592
      /// \brief Creates an iterator with a value.
2593
      ///
2594
      /// Creates an iterator with a value. It iterates on the
2595
      /// keys mapped to the given value.
2596
      /// \param map The IterableBoolMap.
2597
      /// \param value The value.
2598
      ItemIt(const IterableBoolMap& map, bool value)
2599
        : Parent(value ? 
2600
                 (map._sep > 0 ?
2601
                  map._array[map._sep - 1] : INVALID) :
2602
                 (map._sep < int(map._array.size()) ?
2603
                  map._array.back() : INVALID)), _map(&map) {}
2604

	
2605
      /// \brief Invalid constructor \& conversion.
2606
      ///
2607
      /// This constructor initializes the iterator to be invalid.
2608
      /// \sa Invalid for more details.
2609
      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
2610

	
2611
      /// \brief Increment operator.
2612
      ///
2613
      /// Increment operator.
2614
      ItemIt& operator++() {
2615
        int pos = _map->position(*this);
2616
        int _sep = pos >= _map->_sep ? _map->_sep : 0;
2617
        Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);
2618
        return *this;
2619
      }
2620

	
2621
    private:
2622
      const IterableBoolMap* _map;
2623
    };
2624

	
2625
  protected:
2626

	
2627
    virtual void add(const Key& key) {
2628
      Parent::add(key);
2629
      Parent::set(key, _array.size());
2630
      _array.push_back(key);
2631
    }
2632

	
2633
    virtual void add(const std::vector<Key>& keys) {
2634
      Parent::add(keys);
2635
      for (int i = 0; i < int(keys.size()); ++i) {
2636
        Parent::set(keys[i], _array.size());
2637
        _array.push_back(keys[i]);
2638
      }
2639
    }
2640

	
2641
    virtual void erase(const Key& key) {
2642
      int pos = position(key);
2643
      if (pos < _sep) {
2644
        --_sep;
2645
        Parent::set(_array[_sep], pos);
2646
        _array[pos] = _array[_sep];
2647
        Parent::set(_array.back(), _sep);
2648
        _array[_sep] = _array.back();
2649
        _array.pop_back();
2650
      } else {
2651
        Parent::set(_array.back(), pos);
2652
        _array[pos] = _array.back();
2653
        _array.pop_back();
2654
      }
2655
      Parent::erase(key);
2656
    }
2657

	
2658
    virtual void erase(const std::vector<Key>& keys) {
2659
      for (int i = 0; i < int(keys.size()); ++i) {
2660
        int pos = position(keys[i]);
2661
        if (pos < _sep) {
2662
          --_sep;
2663
          Parent::set(_array[_sep], pos);
2664
          _array[pos] = _array[_sep];
2665
          Parent::set(_array.back(), _sep);
2666
          _array[_sep] = _array.back();
2667
          _array.pop_back();
2668
        } else {
2669
          Parent::set(_array.back(), pos);
2670
          _array[pos] = _array.back();
2671
          _array.pop_back();
2672
        }
2673
      }
2674
      Parent::erase(keys);
2675
    }
2676

	
2677
    virtual void build() {
2678
      Parent::build();
2679
      typename Parent::Notifier* nf = Parent::notifier();
2680
      Key it;
2681
      for (nf->first(it); it != INVALID; nf->next(it)) {
2682
        Parent::set(it, _array.size());
2683
        _array.push_back(it);
2684
      }
2685
      _sep = 0;
2686
    }
2687

	
2688
    virtual void clear() {
2689
      _array.clear();
2690
      _sep = 0;
2691
      Parent::clear();
2692
    }
2693

	
2694
  };
2695

	
2696

	
2697
  namespace _maps_bits {
2698
    template <typename Item>
2699
    struct IterableIntMapNode {
2700
      IterableIntMapNode() : value(-1) {}
2701
      IterableIntMapNode(int _value) : value(_value) {}
2702
      Item prev, next;
2703
      int value;
2704
    };
2705
  }
2706

	
2707
  /// \brief Dynamic iterable integer map.
2708
  ///
2709
  /// This class provides a special graph map type which can store an
2710
  /// integer value for graph items (\c Node, \c Arc or \c Edge).
2711
  /// For each non-negative value it is possible to iterate on the keys
2712
  /// mapped to the value.
2713
  ///
2714
  /// This type is a reference map, so it can be modified with the
2715
  /// subscription operator.
2716
  ///
2717
  /// \note The size of the data structure depends on the largest
2718
  /// value in the map.
2719
  ///
2720
  /// \tparam GR The graph type.
2721
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
2722
  /// \c GR::Edge).
2723
  ///
2724
  /// \see IterableBoolMap, IterableValueMap
2725
  /// \see CrossRefMap
2726
  template <typename GR, typename K>
2727
  class IterableIntMap
2728
    : protected ItemSetTraits<GR, K>::
2729
        template Map<_maps_bits::IterableIntMapNode<K> >::Type {
2730
  public:
2731
    typedef typename ItemSetTraits<GR, K>::
2732
      template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;
2733

	
2734
    /// The key type
2735
    typedef K Key;
2736
    /// The value type
2737
    typedef int Value;
2738
    /// The graph type
2739
    typedef GR Graph;
2740

	
2741
    /// \brief Constructor of the map.
2742
    ///
2743
    /// Constructor of the map. It sets all values to -1.
2744
    explicit IterableIntMap(const Graph& graph)
2745
      : Parent(graph) {}
2746

	
2747
    /// \brief Constructor of the map with a given value.
2748
    ///
2749
    /// Constructor of the map with a given value.
2750
    explicit IterableIntMap(const Graph& graph, int value)
2751
      : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
2752
      if (value >= 0) {
2753
        for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
2754
          lace(it);
2755
        }
2756
      }
2757
    }
2758

	
2759
  private:
2760

	
2761
    void unlace(const Key& key) {
2762
      typename Parent::Value& node = Parent::operator[](key);
2763
      if (node.value < 0) return;
2764
      if (node.prev != INVALID) {
2765
        Parent::operator[](node.prev).next = node.next;
2766
      } else {
2767
        _first[node.value] = node.next;
2768
      }
2769
      if (node.next != INVALID) {
2770
        Parent::operator[](node.next).prev = node.prev;
2771
      }
2772
      while (!_first.empty() && _first.back() == INVALID) {
2773
        _first.pop_back();
2774
      }
2775
    }
2776

	
2777
    void lace(const Key& key) {
2778
      typename Parent::Value& node = Parent::operator[](key);
2779
      if (node.value < 0) return;
2780
      if (node.value >= int(_first.size())) {
2781
        _first.resize(node.value + 1, INVALID);
2782
      }
2783
      node.prev = INVALID;
2784
      node.next = _first[node.value];
2785
      if (node.next != INVALID) {
2786
        Parent::operator[](node.next).prev = key;
2787
      }
2788
      _first[node.value] = key;
2789
    }
2790

	
2791
  public:
2792

	
2793
    /// Indicates that the map is reference map.
2794
    typedef True ReferenceMapTag;
2795

	
2796
    /// \brief Reference to the value of the map.
2797
    ///
2798
    /// This class is similar to the \c int type. It can
2799
    /// be converted to \c int and it has the same operators.
2800
    class Reference {
2801
      friend class IterableIntMap;
2802
    private:
2803
      Reference(IterableIntMap& map, const Key& key)
2804
        : _key(key), _map(map) {}
2805
    public:
2806

	
2807
      Reference& operator=(const Reference& value) {
2808
        _map.set(_key, static_cast<const int&>(value));
2809
         return *this;
2810
      }
2811

	
2812
      operator const int&() const {
2813
        return static_cast<const IterableIntMap&>(_map)[_key];
2814
      }
2815

	
2816
      Reference& operator=(int value) {
2817
        _map.set(_key, value);
2818
        return *this;
2819
      }
2820
      Reference& operator++() {
2821
        _map.set(_key, _map[_key] + 1);
2822
        return *this;
2823
      }
2824
      int operator++(int) {
2825
        int value = _map[_key];
2826
        _map.set(_key, value + 1);
2827
        return value;
2828
      }
2829
      Reference& operator--() {
2830
        _map.set(_key, _map[_key] - 1);
2831
        return *this;
2832
      }
2833
      int operator--(int) {
2834
        int value = _map[_key];
2835
        _map.set(_key, value - 1);
2836
        return value;
2837
      }
2838
      Reference& operator+=(int value) {
2839
        _map.set(_key, _map[_key] + value);
2840
        return *this;
2841
      }
2842
      Reference& operator-=(int value) {
2843
        _map.set(_key, _map[_key] - value);
2844
        return *this;
2845
      }
2846
      Reference& operator*=(int value) {
2847
        _map.set(_key, _map[_key] * value);
2848
        return *this;
2849
      }
2850
      Reference& operator/=(int value) {
2851
        _map.set(_key, _map[_key] / value);
2852
        return *this;
2853
      }
2854
      Reference& operator%=(int value) {
2855
        _map.set(_key, _map[_key] % value);
2856
        return *this;
2857
      }
2858
      Reference& operator&=(int value) {
2859
        _map.set(_key, _map[_key] & value);
2860
        return *this;
2861
      }
2862
      Reference& operator|=(int value) {
2863
        _map.set(_key, _map[_key] | value);
2864
        return *this;
2865
      }
2866
      Reference& operator^=(int value) {
2867
        _map.set(_key, _map[_key] ^ value);
2868
        return *this;
2869
      }
2870
      Reference& operator<<=(int value) {
2871
        _map.set(_key, _map[_key] << value);
2872
        return *this;
2873
      }
2874
      Reference& operator>>=(int value) {
2875
        _map.set(_key, _map[_key] >> value);
2876
        return *this;
2877
      }
2878

	
2879
    private:
2880
      Key _key;
2881
      IterableIntMap& _map;
2882
    };
2883

	
2884
    /// The const reference type.
2885
    typedef const Value& ConstReference;
2886

	
2887
    /// \brief Gives back the maximal value plus one.
2888
    ///
2889
    /// Gives back the maximal value plus one.
2890
    int size() const {
2891
      return _first.size();
2892
    }
2893

	
2894
    /// \brief Set operation of the map.
2895
    ///
2896
    /// Set operation of the map.
2897
    void set(const Key& key, const Value& value) {
2898
      unlace(key);
2899
      Parent::operator[](key).value = value;
2900
      lace(key);
2901
    }
2902

	
2903
    /// \brief Const subscript operator of the map.
2904
    ///
2905
    /// Const subscript operator of the map.
2906
    const Value& operator[](const Key& key) const {
2907
      return Parent::operator[](key).value;
2908
    }
2909

	
2910
    /// \brief Subscript operator of the map.
2911
    ///
2912
    /// Subscript operator of the map.
2913
    Reference operator[](const Key& key) {
2914
      return Reference(*this, key);
2915
    }
2916

	
2917
    /// \brief Iterator for the keys with the same value.
2918
    ///
2919
    /// Iterator for the keys with the same value. It works
2920
    /// like a graph item iterator, it can be converted to
2921
    /// the item type of the map, incremented with \c ++ operator, and
2922
    /// if the iterator leaves the last valid item, it will be equal to
2923
    /// \c INVALID.
2924
    class ItemIt : public Key {
2925
    public:
2926
      typedef Key Parent;
2927

	
2928
      /// \brief Invalid constructor \& conversion.
2929
      ///
2930
      /// This constructor initializes the iterator to be invalid.
2931
      /// \sa Invalid for more details.
2932
      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
2933

	
2934
      /// \brief Creates an iterator with a value.
2935
      ///
2936
      /// Creates an iterator with a value. It iterates on the
2937
      /// keys mapped to the given value.
2938
      /// \param map The IterableIntMap.
2939
      /// \param value The value.
2940
      ItemIt(const IterableIntMap& map, int value) : _map(&map) {
2941
        if (value < 0 || value >= int(_map->_first.size())) {
2942
          Parent::operator=(INVALID);
2943
        } else {
2944
          Parent::operator=(_map->_first[value]);
2945
        }
2946
      }
2947

	
2948
      /// \brief Increment operator.
2949
      ///
2950
      /// Increment operator.
2951
      ItemIt& operator++() {
2952
        Parent::operator=(_map->IterableIntMap::Parent::
2953
                          operator[](static_cast<Parent&>(*this)).next);
2954
        return *this;
2955
      }
2956

	
2957
    private:
2958
      const IterableIntMap* _map;
2959
    };
2960

	
2961
  protected:
2962

	
2963
    virtual void erase(const Key& key) {
2964
      unlace(key);
2965
      Parent::erase(key);
2966
    }
2967

	
2968
    virtual void erase(const std::vector<Key>& keys) {
2969
      for (int i = 0; i < int(keys.size()); ++i) {
2970
        unlace(keys[i]);
2971
      }
2972
      Parent::erase(keys);
2973
    }
2974

	
2975
    virtual void clear() {
2976
      _first.clear();
2977
      Parent::clear();
2978
    }
2979

	
2980
  private:
2981
    std::vector<Key> _first;
2982
  };
2983

	
2984
  namespace _maps_bits {
2985
    template <typename Item, typename Value>
2986
    struct IterableValueMapNode {
2987
      IterableValueMapNode(Value _value = Value()) : value(_value) {}
2988
      Item prev, next;
2989
      Value value;
2990
    };
2991
  }
2992

	
2993
  /// \brief Dynamic iterable map for comparable values.
2994
  ///
2995
  /// This class provides a special graph map type which can store an
2996
  /// comparable value for graph items (\c Node, \c Arc or \c Edge).
2997
  /// For each value it is possible to iterate on the keys mapped to
2998
  /// the value.
2999
  ///
3000
  /// The map stores for each value a linked list with
3001
  /// the items which mapped to the value, and the values are stored
3002
  /// in balanced binary tree. The values of the map can be accessed
3003
  /// with stl compatible forward iterator.
3004
  ///
3005
  /// This type is not reference map, so it cannot be modified with
3006
  /// the subscription operator.
3007
  ///
3008
  /// \tparam GR The graph type.
3009
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
3010
  /// \c GR::Edge).
3011
  /// \tparam V The value type of the map. It can be any comparable
3012
  /// value type.
3013
  ///
3014
  /// \see IterableBoolMap, IterableIntMap
3015
  /// \see CrossRefMap
3016
  template <typename GR, typename K, typename V>
3017
  class IterableValueMap
3018
    : protected ItemSetTraits<GR, K>::
3019
        template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
3020
  public:
3021
    typedef typename ItemSetTraits<GR, K>::
3022
      template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;
3023

	
3024
    /// The key type
3025
    typedef K Key;
3026
    /// The value type
3027
    typedef V Value;
3028
    /// The graph type
3029
    typedef GR Graph;
3030

	
3031
  public:
3032

	
3033
    /// \brief Constructor of the map with a given value.
3034
    ///
3035
    /// Constructor of the map with a given value.
3036
    explicit IterableValueMap(const Graph& graph,
3037
                              const Value& value = Value())
3038
      : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
3039
      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
3040
        lace(it);
3041
      }
3042
    }
3043

	
3044
  protected:
3045

	
3046
    void unlace(const Key& key) {
3047
      typename Parent::Value& node = Parent::operator[](key);
3048
      if (node.prev != INVALID) {
3049
        Parent::operator[](node.prev).next = node.next;
3050
      } else {
3051
        if (node.next != INVALID) {
3052
          _first[node.value] = node.next;
3053
        } else {
3054
          _first.erase(node.value);
3055
        }
3056
      }
3057
      if (node.next != INVALID) {
3058
        Parent::operator[](node.next).prev = node.prev;
3059
      }
3060
    }
3061

	
3062
    void lace(const Key& key) {
3063
      typename Parent::Value& node = Parent::operator[](key);
3064
      typename std::map<Value, Key>::iterator it = _first.find(node.value);
3065
      if (it == _first.end()) {
3066
        node.prev = node.next = INVALID;
3067
        _first.insert(std::make_pair(node.value, key));
3068
      } else {
3069
        node.prev = INVALID;
3070
        node.next = it->second;
3071
        if (node.next != INVALID) {
3072
          Parent::operator[](node.next).prev = key;
3073
        }
3074
        it->second = key;
3075
      }
3076
    }
3077

	
3078
  public:
3079

	
3080
    /// \brief Forward iterator for values.
3081
    ///
3082
    /// This iterator is an stl compatible forward
3083
    /// iterator on the values of the map. The values can
3084
    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
3085
    class ValueIterator
3086
      : public std::iterator<std::forward_iterator_tag, Value> {
3087
      friend class IterableValueMap;
3088
    private:
3089
      ValueIterator(typename std::map<Value, Key>::const_iterator _it)
3090
        : it(_it) {}
3091
    public:
3092

	
3093
      ValueIterator() {}
3094

	
3095
      ValueIterator& operator++() { ++it; return *this; }
3096
      ValueIterator operator++(int) {
3097
        ValueIterator tmp(*this);
3098
        operator++();
3099
        return tmp;
3100
      }
3101

	
3102
      const Value& operator*() const { return it->first; }
3103
      const Value* operator->() const { return &(it->first); }
3104

	
3105
      bool operator==(ValueIterator jt) const { return it == jt.it; }
3106
      bool operator!=(ValueIterator jt) const { return it != jt.it; }
3107

	
3108
    private:
3109
      typename std::map<Value, Key>::const_iterator it;
3110
    };
3111

	
3112
    /// \brief Returns an iterator to the first value.
3113
    ///
3114
    /// Returns an stl compatible iterator to the
3115
    /// first value of the map. The values of the
3116
    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
3117
    /// range.
3118
    ValueIterator beginValue() const {
3119
      return ValueIterator(_first.begin());
3120
    }
3121

	
3122
    /// \brief Returns an iterator after the last value.
3123
    ///
3124
    /// Returns an stl compatible iterator after the
3125
    /// last value of the map. The values of the
3126
    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
3127
    /// range.
3128
    ValueIterator endValue() const {
3129
      return ValueIterator(_first.end());
3130
    }
3131

	
3132
    /// \brief Set operation of the map.
3133
    ///
3134
    /// Set operation of the map.
3135
    void set(const Key& key, const Value& value) {
3136
      unlace(key);
3137
      Parent::operator[](key).value = value;
3138
      lace(key);
3139
    }
3140

	
3141
    /// \brief Const subscript operator of the map.
3142
    ///
3143
    /// Const subscript operator of the map.
3144
    const Value& operator[](const Key& key) const {
3145
      return Parent::operator[](key).value;
3146
    }
3147

	
3148
    /// \brief Iterator for the keys with the same value.
3149
    ///
3150
    /// Iterator for the keys with the same value. It works
3151
    /// like a graph item iterator, it can be converted to
3152
    /// the item type of the map, incremented with \c ++ operator, and
3153
    /// if the iterator leaves the last valid item, it will be equal to
3154
    /// \c INVALID.
3155
    class ItemIt : public Key {
3156
    public:
3157
      typedef Key Parent;
3158

	
3159
      /// \brief Invalid constructor \& conversion.
3160
      ///
3161
      /// This constructor initializes the iterator to be invalid.
3162
      /// \sa Invalid for more details.
3163
      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
3164

	
3165
      /// \brief Creates an iterator with a value.
3166
      ///
3167
      /// Creates an iterator with a value. It iterates on the
3168
      /// keys which have the given value.
3169
      /// \param map The IterableValueMap
3170
      /// \param value The value
3171
      ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
3172
        typename std::map<Value, Key>::const_iterator it =
3173
          map._first.find(value);
3174
        if (it == map._first.end()) {
3175
          Parent::operator=(INVALID);
3176
        } else {
3177
          Parent::operator=(it->second);
3178
        }
3179
      }
3180

	
3181
      /// \brief Increment operator.
3182
      ///
3183
      /// Increment Operator.
3184
      ItemIt& operator++() {
3185
        Parent::operator=(_map->IterableValueMap::Parent::
3186
                          operator[](static_cast<Parent&>(*this)).next);
3187
        return *this;
3188
      }
3189

	
3190

	
3191
    private:
3192
      const IterableValueMap* _map;
3193
    };
3194

	
3195
  protected:
3196

	
3197
    virtual void add(const Key& key) {
3198
      Parent::add(key);
3199
      unlace(key);
3200
    }
3201

	
3202
    virtual void add(const std::vector<Key>& keys) {
3203
      Parent::add(keys);
3204
      for (int i = 0; i < int(keys.size()); ++i) {
3205
        lace(keys[i]);
3206
      }
3207
    }
3208

	
3209
    virtual void erase(const Key& key) {
3210
      unlace(key);
3211
      Parent::erase(key);
3212
    }
3213

	
3214
    virtual void erase(const std::vector<Key>& keys) {
3215
      for (int i = 0; i < int(keys.size()); ++i) {
3216
        unlace(keys[i]);
3217
      }
3218
      Parent::erase(keys);
3219
    }
3220

	
3221
    virtual void build() {
3222
      Parent::build();
3223
      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
3224
        lace(it);
3225
      }
3226
    }
3227

	
3228
    virtual void clear() {
3229
      _first.clear();
3230
      Parent::clear();
3231
    }
3232

	
3233
  private:
3234
    std::map<Value, Key> _first;
3235
  };
3236

	
2341 3237
  /// \brief Map of the source nodes of arcs in a digraph.
2342 3238
  ///
2343 3239
  /// SourceMap provides access for the source node of each arc in a digraph,
2344 3240
  /// which is returned by the \c source() function of the digraph.
2345 3241
  /// \tparam GR The digraph type.
2346 3242
  /// \see TargetMap
... ...
@@ -2504,13 +3400,13 @@
2504 3400
  ///
2505 3401
  /// This map returns the in-degree of a node. Once it is constructed,
2506 3402
  /// the degrees are stored in a standard \c NodeMap, so each query is done
2507 3403
  /// in constant time. On the other hand, the values are updated automatically
2508 3404
  /// whenever the digraph changes.
2509 3405
  ///
2510
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
3406
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
2511 3407
  /// may provide alternative ways to modify the digraph.
2512 3408
  /// The correct behavior of InDegMap is not guarantied if these additional
2513 3409
  /// features are used. For example the functions
2514 3410
  /// \ref ListDigraph::changeSource() "changeSource()",
2515 3411
  /// \ref ListDigraph::changeTarget() "changeTarget()" and
2516 3412
  /// \ref ListDigraph::reverseArc() "reverseArc()"
... ...
@@ -2520,13 +3416,13 @@
2520 3416
  template <typename GR>
2521 3417
  class InDegMap
2522 3418
    : protected ItemSetTraits<GR, typename GR::Arc>
2523 3419
      ::ItemNotifier::ObserverBase {
2524 3420

	
2525 3421
  public:
2526
    
3422

	
2527 3423
    /// The graph type of InDegMap
2528 3424
    typedef GR Graph;
2529 3425
    typedef GR Digraph;
2530 3426
    /// The key type
2531 3427
    typedef typename Digraph::Node Key;
2532 3428
    /// The value type
... ...
@@ -2634,13 +3530,13 @@
2634 3530
  ///
2635 3531
  /// This map returns the out-degree of a node. Once it is constructed,
2636 3532
  /// the degrees are stored in a standard \c NodeMap, so each query is done
2637 3533
  /// in constant time. On the other hand, the values are updated automatically
2638 3534
  /// whenever the digraph changes.
2639 3535
  ///
2640
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
3536
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
2641 3537
  /// may provide alternative ways to modify the digraph.
2642 3538
  /// The correct behavior of OutDegMap is not guarantied if these additional
2643 3539
  /// features are used. For example the functions
2644 3540
  /// \ref ListDigraph::changeSource() "changeSource()",
2645 3541
  /// \ref ListDigraph::changeTarget() "changeTarget()" and
2646 3542
  /// \ref ListDigraph::reverseArc() "reverseArc()"
Ignore white space 6 line context
... ...
@@ -28,12 +28,15 @@
28 28

	
29 29
#include <lemon/lgf_reader.h>
30 30
#include <lemon/dijkstra.h>
31 31
#include <lemon/maps.h>
32 32

	
33 33
#include <lemon/bin_heap.h>
34
#include <lemon/fib_heap.h>
35
#include <lemon/radix_heap.h>
36
#include <lemon/bucket_heap.h>
34 37

	
35 38
#include "test_tools.h"
36 39

	
37 40
using namespace lemon;
38 41
using namespace lemon::concepts;
39 42

	
... ...
@@ -180,8 +183,42 @@
180 183

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

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

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

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

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

	
211
  {
212
    typedef BucketHeap<ItemIntMap> IntHeap;
213
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
214
    heapSortTest<IntHeap>();
215
    heapIncreaseTest<IntHeap>();
216

	
217
    typedef BucketHeap<IntNodeMap > NodeHeap;
218
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
219
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
220
  }
221

	
222

	
186 223
  return 0;
187 224
}
Ignore white space 12 line context
... ...
@@ -20,12 +20,13 @@
20 20
#include <set>
21 21

	
22 22
#include <lemon/concept_check.h>
23 23
#include <lemon/concepts/maps.h>
24 24
#include <lemon/maps.h>
25 25
#include <lemon/list_graph.h>
26
#include <lemon/smart_graph.h>
26 27

	
27 28
#include "test_tools.h"
28 29

	
29 30
using namespace lemon;
30 31
using namespace lemon::concepts;
31 32

	
... ...
@@ -491,8 +492,195 @@
491 492

	
492 493
    it = map.beginValue();
493 494
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
494 495
          it == map.endValue(), "Wrong value iterator");
495 496
  }
496 497

	
498
  // Iterable bool map
499
  {
500
    typedef SmartGraph Graph;
501
    typedef SmartGraph::Node Item;
502

	
503
    typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
504
    checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
505

	
506
    const int num = 10;
507
    Graph g;
508
    std::vector<Item> items;
509
    for (int i = 0; i < num; ++i) {
510
      items.push_back(g.addNode());
511
    }
512

	
513
    Ibm map1(g, true);
514
    int n = 0;
515
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
516
      check(map1[static_cast<Item>(it)], "Wrong TrueIt");
517
      ++n;
518
    }
519
    check(n == num, "Wrong number");
520

	
521
    n = 0;
522
    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
523
        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
524
        ++n;
525
    }
526
    check(n == num, "Wrong number");
527
    check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
528
    check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
529

	
530
    map1[items[5]] = true;
531

	
532
    n = 0;
533
    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
534
        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
535
        ++n;
536
    }
537
    check(n == num, "Wrong number");
538

	
539
    map1[items[num / 2]] = false;
540
    check(map1[items[num / 2]] == false, "Wrong map value");
541

	
542
    n = 0;
543
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
544
        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
545
        ++n;
546
    }
547
    check(n == num - 1, "Wrong number");
548

	
549
    n = 0;
550
    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
551
        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
552
        ++n;
553
    }
554
    check(n == 1, "Wrong number");
555

	
556
    map1[items[0]] = false;
557
    check(map1[items[0]] == false, "Wrong map value");
558

	
559
    map1[items[num - 1]] = false;
560
    check(map1[items[num - 1]] == false, "Wrong map value");
561

	
562
    n = 0;
563
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
564
        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
565
        ++n;
566
    }
567
    check(n == num - 3, "Wrong number");
568
    check(map1.trueNum() == num - 3, "Wrong number");
569

	
570
    n = 0;
571
    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
572
        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
573
        ++n;
574
    }
575
    check(n == 3, "Wrong number");
576
    check(map1.falseNum() == 3, "Wrong number");
577
  }
578

	
579
  // Iterable int map
580
  {
581
    typedef SmartGraph Graph;
582
    typedef SmartGraph::Node Item;
583
    typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
584

	
585
    checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
586

	
587
    const int num = 10;
588
    Graph g;
589
    std::vector<Item> items;
590
    for (int i = 0; i < num; ++i) {
591
      items.push_back(g.addNode());
592
    }
593

	
594
    Iim map1(g);
595
    check(map1.size() == 0, "Wrong size");
596

	
597
    for (int i = 0; i < num; ++i) {
598
      map1[items[i]] = i;
599
    }
600
    check(map1.size() == num, "Wrong size");
601

	
602
    for (int i = 0; i < num; ++i) {
603
      Iim::ItemIt it(map1, i);
604
      check(static_cast<Item>(it) == items[i], "Wrong value");
605
      ++it;
606
      check(static_cast<Item>(it) == INVALID, "Wrong value");
607
    }
608

	
609
    for (int i = 0; i < num; ++i) {
610
      map1[items[i]] = i % 2;
611
    }
612
    check(map1.size() == 2, "Wrong size");
613

	
614
    int n = 0;
615
    for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
616
      check(map1[static_cast<Item>(it)] == 0, "Wrong value");
617
      ++n;
618
    }
619
    check(n == (num + 1) / 2, "Wrong number");
620

	
621
    for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
622
      check(map1[static_cast<Item>(it)] == 1, "Wrong value");
623
      ++n;
624
    }
625
    check(n == num, "Wrong number");
626

	
627
  }
628

	
629
  // Iterable value map
630
  {
631
    typedef SmartGraph Graph;
632
    typedef SmartGraph::Node Item;
633
    typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
634

	
635
    checkConcept<ReadWriteMap<Item, double>, Ivm>();
636

	
637
    const int num = 10;
638
    Graph g;
639
    std::vector<Item> items;
640
    for (int i = 0; i < num; ++i) {
641
      items.push_back(g.addNode());
642
    }
643

	
644
    Ivm map1(g, 0.0);
645
    check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
646
    check(*map1.beginValue() == 0.0, "Wrong value");
647

	
648
    for (int i = 0; i < num; ++i) {
649
      map1.set(items[i], static_cast<double>(i));
650
    }
651
    check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
652

	
653
    for (int i = 0; i < num; ++i) {
654
      Ivm::ItemIt it(map1, static_cast<double>(i));
655
      check(static_cast<Item>(it) == items[i], "Wrong value");
656
      ++it;
657
      check(static_cast<Item>(it) == INVALID, "Wrong value");
658
    }
659

	
660
    for (Ivm::ValueIterator vit = map1.beginValue();
661
         vit != map1.endValue(); ++vit) {
662
      check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
663
            "Wrong ValueIterator");
664
    }
665

	
666
    for (int i = 0; i < num; ++i) {
667
      map1.set(items[i], static_cast<double>(i % 2));
668
    }
669
    check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
670

	
671
    int n = 0;
672
    for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
673
      check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
674
      ++n;
675
    }
676
    check(n == (num + 1) / 2, "Wrong number");
677

	
678
    for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
679
      check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
680
      ++n;
681
    }
682
    check(n == num, "Wrong number");
683

	
684
  }
497 685
  return 0;
498 686
}
0 comments (0 inline)