gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge GLPK fix #337 with CMAKE improvements
0 7 3
merge default
0 files changed with 1648 insertions and 114 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
... ...
@@ -14,121 +14,124 @@
14 14
	lemon/lp_base.cc \
15 15
	lemon/lp_skeleton.cc \
16 16
	lemon/random.cc \
17 17
	lemon/bits/windows.cc
18 18

	
19 19
nodist_lemon_HEADERS = lemon/config.h	
20 20

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

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

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

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

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

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

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

	
56 56
lemon_HEADERS += \
57 57
	lemon/adaptors.h \
58 58
	lemon/arg_parser.h \
59 59
	lemon/assert.h \
60 60
	lemon/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 \
68 69
	lemon/counter.h \
69 70
	lemon/core.h \
70 71
	lemon/cplex.h \
71 72
	lemon/dfs.h \
72 73
	lemon/dijkstra.h \
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 \
85 87
	lemon/kruskal.h \
86 88
	lemon/hao_orlin.h \
87 89
	lemon/lgf_reader.h \
88 90
	lemon/lgf_writer.h \
89 91
	lemon/list_graph.h \
90 92
	lemon/lp.h \
91 93
	lemon/lp_base.h \
92 94
	lemon/lp_skeleton.h \
93 95
	lemon/list_graph.h \
94 96
	lemon/maps.h \
95 97
	lemon/matching.h \
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 \
108 111
	lemon/tolerance.h \
109 112
	lemon/unionfind.h \
110 113
	lemon/bits/windows.h
111 114

	
112 115
bits_HEADERS += \
113 116
	lemon/bits/alteration_notifier.h \
114 117
	lemon/bits/array_map.h \
115 118
	lemon/bits/bezier.h \
116 119
	lemon/bits/default_map.h \
117 120
	lemon/bits/edge_set_extender.h \
118 121
	lemon/bits/enable_if.h \
119 122
	lemon/bits/graph_adaptor_extender.h \
120 123
	lemon/bits/graph_extender.h \
121 124
	lemon/bits/map_extender.h \
122 125
	lemon/bits/path_dump.h \
123 126
	lemon/bits/solver_bits.h \
124 127
	lemon/bits/traits.h \
125 128
	lemon/bits/variant.h \
126 129
	lemon/bits/vector_map.h
127 130

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

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

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

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

	
30 30
namespace lemon {
31 31

	
32 32
  ///\ingroup 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.
72 72
    ///
73 73
    /// The item-int map must be initialized in such way that it assigns
74 74
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
75 75
    enum State {
76 76
      IN_HEAP = 0,    ///< = 0.
77 77
      PRE_HEAP = -1,  ///< = -1.
78 78
      POST_HEAP = -2  ///< = -2.
79 79
    };
80 80

	
81 81
  private:
82 82
    std::vector<Pair> _data;
83 83
    Compare _comp;
84 84
    ItemIntMap &_iim;
85 85

	
86 86
  public:
87 87
    /// \brief The constructor.
88 88
    ///
89 89
    /// The constructor.
90 90
    /// \param map should be given to the constructor, since it is used
91 91
    /// internally to handle the cross references. The value of the map
92 92
    /// must be \c PRE_HEAP (<tt>-1</tt>) for every item.
93 93
    explicit BinHeap(ItemIntMap &map) : _iim(map) {}
94 94

	
95 95
    /// \brief The constructor.
96 96
    ///
97 97
    /// The constructor.
98 98
    /// \param map should be given to the constructor, since it is used
99 99
    /// internally to handle the cross references. The value of the map
100 100
    /// should be PRE_HEAP (-1) for each element.
101 101
    ///
102 102
    /// \param comp The comparator function object.
103 103
    BinHeap(ItemIntMap &map, const Compare &comp)
104 104
      : _iim(map), _comp(comp) {}
105 105

	
106 106

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

	
112 112
    /// \brief Checks if the heap stores no items.
113 113
    ///
Ignore white space 6 line context
... ...
@@ -4,325 +4,329 @@
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BITS_MAP_EXTENDER_H
20 20
#define LEMON_BITS_MAP_EXTENDER_H
21 21

	
22 22
#include <iterator>
23 23

	
24 24
#include <lemon/bits/traits.h>
25 25

	
26 26
#include <lemon/concept_check.h>
27 27
#include <lemon/concepts/maps.h>
28 28

	
29 29
//\file
30 30
//\brief Extenders for iterable maps.
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  // \ingroup graphbits
35 35
  //
36 36
  // \brief Extender for maps
37 37
  template <typename _Map>
38 38
  class MapExtender : public _Map {
39 39
    typedef _Map Parent;
40 40
    typedef typename Parent::GraphType GraphType;
41 41

	
42 42
  public:
43 43

	
44 44
    typedef MapExtender Map;
45 45
    typedef typename Parent::Key Item;
46 46

	
47 47
    typedef typename Parent::Key Key;
48 48
    typedef typename Parent::Value Value;
49 49
    typedef typename Parent::Reference Reference;
50 50
    typedef typename Parent::ConstReference ConstReference;
51 51

	
52
    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
53

	
52 54
    class MapIt;
53 55
    class ConstMapIt;
54 56

	
55 57
    friend class MapIt;
56 58
    friend class ConstMapIt;
57 59

	
58 60
  public:
59 61

	
60 62
    MapExtender(const GraphType& graph)
61 63
      : Parent(graph) {}
62 64

	
63 65
    MapExtender(const GraphType& graph, const Value& value)
64 66
      : Parent(graph, value) {}
65 67

	
66 68
  private:
67 69
    MapExtender& operator=(const MapExtender& cmap) {
68 70
      return operator=<MapExtender>(cmap);
69 71
    }
70 72

	
71 73
    template <typename CMap>
72 74
    MapExtender& operator=(const CMap& cmap) {
73 75
      Parent::operator=(cmap);
74 76
      return *this;
75 77
    }
76 78

	
77 79
  public:
78 80
    class MapIt : public Item {
79 81
      typedef Item Parent;
80 82

	
81 83
    public:
82 84

	
83 85
      typedef typename Map::Value Value;
84 86

	
85
      MapIt() {}
87
      MapIt() : map(NULL) {}
86 88

	
87
      MapIt(Invalid i) : Parent(i) { }
89
      MapIt(Invalid i) : Parent(i), map(NULL) {}
88 90

	
89
      explicit MapIt(Map& _map) : map(_map) {
90
        map.notifier()->first(*this);
91
      explicit MapIt(Map& _map) : map(&_map) {
92
        map->notifier()->first(*this);
91 93
      }
92 94

	
93 95
      MapIt(const Map& _map, const Item& item)
94
        : Parent(item), map(_map) {}
96
        : Parent(item), map(&_map) {}
95 97

	
96 98
      MapIt& operator++() {
97
        map.notifier()->next(*this);
99
        map->notifier()->next(*this);
98 100
        return *this;
99 101
      }
100 102

	
101 103
      typename MapTraits<Map>::ConstReturnValue operator*() const {
102
        return map[*this];
104
        return (*map)[*this];
103 105
      }
104 106

	
105 107
      typename MapTraits<Map>::ReturnValue operator*() {
106
        return map[*this];
108
        return (*map)[*this];
107 109
      }
108 110

	
109 111
      void set(const Value& value) {
110
        map.set(*this, value);
112
        map->set(*this, value);
111 113
      }
112 114

	
113 115
    protected:
114
      Map& map;
116
      Map* map;
115 117

	
116 118
    };
117 119

	
118 120
    class ConstMapIt : public Item {
119 121
      typedef Item Parent;
120 122

	
121 123
    public:
122 124

	
123 125
      typedef typename Map::Value Value;
124 126

	
125
      ConstMapIt() {}
127
      ConstMapIt() : map(NULL) {}
126 128

	
127
      ConstMapIt(Invalid i) : Parent(i) { }
129
      ConstMapIt(Invalid i) : Parent(i), map(NULL) {}
128 130

	
129
      explicit ConstMapIt(Map& _map) : map(_map) {
130
        map.notifier()->first(*this);
131
      explicit ConstMapIt(Map& _map) : map(&_map) {
132
        map->notifier()->first(*this);
131 133
      }
132 134

	
133 135
      ConstMapIt(const Map& _map, const Item& item)
134 136
        : Parent(item), map(_map) {}
135 137

	
136 138
      ConstMapIt& operator++() {
137
        map.notifier()->next(*this);
139
        map->notifier()->next(*this);
138 140
        return *this;
139 141
      }
140 142

	
141 143
      typename MapTraits<Map>::ConstReturnValue operator*() const {
142 144
        return map[*this];
143 145
      }
144 146

	
145 147
    protected:
146
      const Map& map;
148
      const Map* map;
147 149
    };
148 150

	
149 151
    class ItemIt : public Item {
150 152
      typedef Item Parent;
151 153

	
152 154
    public:
155
      ItemIt() : map(NULL) {}
153 156

	
154
      ItemIt() {}
155 157

	
156
      ItemIt(Invalid i) : Parent(i) { }
158
      ItemIt(Invalid i) : Parent(i), map(NULL) {}
157 159

	
158
      explicit ItemIt(Map& _map) : map(_map) {
159
        map.notifier()->first(*this);
160
      explicit ItemIt(Map& _map) : map(&_map) {
161
        map->notifier()->first(*this);
160 162
      }
161 163

	
162 164
      ItemIt(const Map& _map, const Item& item)
163
        : Parent(item), map(_map) {}
165
        : Parent(item), map(&_map) {}
164 166

	
165 167
      ItemIt& operator++() {
166
        map.notifier()->next(*this);
168
        map->notifier()->next(*this);
167 169
        return *this;
168 170
      }
169 171

	
170 172
    protected:
171
      const Map& map;
173
      const Map* map;
172 174

	
173 175
    };
174 176
  };
175 177

	
176 178
  // \ingroup graphbits
177 179
  //
178 180
  // \brief Extender for maps which use a subset of the items.
179 181
  template <typename _Graph, typename _Map>
180 182
  class SubMapExtender : public _Map {
181 183
    typedef _Map Parent;
182 184
    typedef _Graph GraphType;
183 185

	
184 186
  public:
185 187

	
186 188
    typedef SubMapExtender Map;
187 189
    typedef typename Parent::Key Item;
188 190

	
189 191
    typedef typename Parent::Key Key;
190 192
    typedef typename Parent::Value Value;
191 193
    typedef typename Parent::Reference Reference;
192 194
    typedef typename Parent::ConstReference ConstReference;
193 195

	
196
    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
197

	
194 198
    class MapIt;
195 199
    class ConstMapIt;
196 200

	
197 201
    friend class MapIt;
198 202
    friend class ConstMapIt;
199 203

	
200 204
  public:
201 205

	
202 206
    SubMapExtender(const GraphType& _graph)
203 207
      : Parent(_graph), graph(_graph) {}
204 208

	
205 209
    SubMapExtender(const GraphType& _graph, const Value& _value)
206 210
      : Parent(_graph, _value), graph(_graph) {}
207 211

	
208 212
  private:
209 213
    SubMapExtender& operator=(const SubMapExtender& cmap) {
210 214
      return operator=<MapExtender>(cmap);
211 215
    }
212 216

	
213 217
    template <typename CMap>
214 218
    SubMapExtender& operator=(const CMap& cmap) {
215 219
      checkConcept<concepts::ReadMap<Key, Value>, CMap>();
216 220
      Item it;
217 221
      for (graph.first(it); it != INVALID; graph.next(it)) {
218 222
        Parent::set(it, cmap[it]);
219 223
      }
220 224
      return *this;
221 225
    }
222 226

	
223 227
  public:
224 228
    class MapIt : public Item {
225 229
      typedef Item Parent;
226 230

	
227 231
    public:
228 232
      typedef typename Map::Value Value;
229 233

	
230
      MapIt() {}
234
      MapIt() : map(NULL) {}
231 235

	
232
      MapIt(Invalid i) : Parent(i) { }
236
      MapIt(Invalid i) : Parent(i), map(NULL) { }
233 237

	
234
      explicit MapIt(Map& _map) : map(_map) {
235
        map.graph.first(*this);
238
      explicit MapIt(Map& _map) : map(&_map) {
239
        map->graph.first(*this);
236 240
      }
237 241

	
238 242
      MapIt(const Map& _map, const Item& item)
239
        : Parent(item), map(_map) {}
243
        : Parent(item), map(&_map) {}
240 244

	
241 245
      MapIt& operator++() {
242
        map.graph.next(*this);
246
        map->graph.next(*this);
243 247
        return *this;
244 248
      }
245 249

	
246 250
      typename MapTraits<Map>::ConstReturnValue operator*() const {
247
        return map[*this];
251
        return (*map)[*this];
248 252
      }
249 253

	
250 254
      typename MapTraits<Map>::ReturnValue operator*() {
251
        return map[*this];
255
        return (*map)[*this];
252 256
      }
253 257

	
254 258
      void set(const Value& value) {
255
        map.set(*this, value);
259
        map->set(*this, value);
256 260
      }
257 261

	
258 262
    protected:
259
      Map& map;
263
      Map* map;
260 264

	
261 265
    };
262 266

	
263 267
    class ConstMapIt : public Item {
264 268
      typedef Item Parent;
265 269

	
266 270
    public:
267 271

	
268 272
      typedef typename Map::Value Value;
269 273

	
270
      ConstMapIt() {}
274
      ConstMapIt() : map(NULL) {}
271 275

	
272
      ConstMapIt(Invalid i) : Parent(i) { }
276
      ConstMapIt(Invalid i) : Parent(i), map(NULL) { }
273 277

	
274
      explicit ConstMapIt(Map& _map) : map(_map) {
275
        map.graph.first(*this);
278
      explicit ConstMapIt(Map& _map) : map(&_map) {
279
        map->graph.first(*this);
276 280
      }
277 281

	
278 282
      ConstMapIt(const Map& _map, const Item& item)
279
        : Parent(item), map(_map) {}
283
        : Parent(item), map(&_map) {}
280 284

	
281 285
      ConstMapIt& operator++() {
282
        map.graph.next(*this);
286
        map->graph.next(*this);
283 287
        return *this;
284 288
      }
285 289

	
286 290
      typename MapTraits<Map>::ConstReturnValue operator*() const {
287
        return map[*this];
291
        return (*map)[*this];
288 292
      }
289 293

	
290 294
    protected:
291
      const Map& map;
295
      const Map* map;
292 296
    };
293 297

	
294 298
    class ItemIt : public Item {
295 299
      typedef Item Parent;
296 300

	
297 301
    public:
302
      ItemIt() : map(NULL) {}
298 303

	
299
      ItemIt() {}
300 304

	
301
      ItemIt(Invalid i) : Parent(i) { }
305
      ItemIt(Invalid i) : Parent(i), map(NULL) { }
302 306

	
303
      explicit ItemIt(Map& _map) : map(_map) {
304
        map.graph.first(*this);
307
      explicit ItemIt(Map& _map) : map(&_map) {
308
        map->graph.first(*this);
305 309
      }
306 310

	
307 311
      ItemIt(const Map& _map, const Item& item)
308
        : Parent(item), map(_map) {}
312
        : Parent(item), map(&_map) {}
309 313

	
310 314
      ItemIt& operator++() {
311
        map.graph.next(*this);
315
        map->graph.next(*this);
312 316
        return *this;
313 317
      }
314 318

	
315 319
    protected:
316
      const Map& map;
320
      const Map* map;
317 321

	
318 322
    };
319 323

	
320 324
  private:
321 325

	
322 326
    const GraphType& graph;
323 327

	
324 328
  };
325 329

	
326 330
}
327 331

	
328 332
#endif
Ignore white space 6 line context
... ...
@@ -137,80 +137,81 @@
137 137

	
138 138
      template<typename _ReadWriteMap>
139 139
      struct Constraints {
140 140
        void constraints() {
141 141
          checkConcept<ReadMap<K, T>, _ReadWriteMap >();
142 142
          checkConcept<WriteMap<K, T>, _ReadWriteMap >();
143 143
        }
144 144
      };
145 145
    };
146 146

	
147 147

	
148 148
    /// Dereferable map concept
149 149

	
150 150
    /// Dereferable map concept.
151 151
    ///
152 152
    template<typename K, typename T, typename R, typename CR>
153 153
    class ReferenceMap : public ReadWriteMap<K,T>
154 154
    {
155 155
    public:
156 156
      /// Tag for reference maps.
157 157
      typedef True ReferenceMapTag;
158 158
      /// The key type of the map.
159 159
      typedef K Key;
160 160
      /// \brief The value type of the map.
161 161
      /// (The type of objects associated with the keys).
162 162
      typedef T Value;
163 163
      /// The reference type of the map.
164 164
      typedef R Reference;
165 165
      /// The const reference type of the map.
166 166
      typedef CR ConstReference;
167 167

	
168 168
    public:
169 169

	
170 170
      /// Returns a reference to the value associated with the given key.
171 171
      Reference operator[](const Key &) {
172 172
        return *static_cast<Value *>(0);
173 173
      }
174 174

	
175 175
      /// Returns a const reference to the value associated with the given key.
176 176
      ConstReference operator[](const Key &) const {
177 177
        return *static_cast<Value *>(0);
178 178
      }
179 179

	
180 180
      /// Sets the value associated with the given key.
181 181
      void set(const Key &k,const Value &t) { operator[](k)=t; }
182 182

	
183 183
      template<typename _ReferenceMap>
184 184
      struct Constraints {
185
        void constraints() {
185
        typename enable_if<typename _ReferenceMap::ReferenceMapTag, void>::type
186
        constraints() {
186 187
          checkConcept<ReadWriteMap<K, T>, _ReferenceMap >();
187 188
          ref = m[key];
188 189
          m[key] = val;
189 190
          m[key] = ref;
190 191
          m[key] = cref;
191 192
          own_ref = m[own_key];
192 193
          m[own_key] = own_val;
193 194
          m[own_key] = own_ref;
194 195
          m[own_key] = own_cref;
195 196
          m[key] = m[own_key];
196 197
          m[own_key] = m[key];
197 198
        }
198 199
        const Key& key;
199 200
        Value& val;
200 201
        Reference ref;
201 202
        ConstReference cref;
202 203
        const typename _ReferenceMap::Key& own_key;
203 204
        typename _ReferenceMap::Value& own_val;
204 205
        typename _ReferenceMap::Reference own_ref;
205 206
        typename _ReferenceMap::ConstReference own_cref;
206 207
        _ReferenceMap& m;
207 208
      };
208 209
    };
209 210

	
210 211
    // @}
211 212

	
212 213
  } //namespace concepts
213 214

	
214 215
} //namespace lemon
215 216

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

	
19 19
#ifndef LEMON_GLPK_H
20 20
#define LEMON_GLPK_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-GLPK lp solver interface.
24 24
///\ingroup lp_group
25 25

	
26 26
#include <lemon/lp_base.h>
27 27

	
28
// forward declaration
29
#if !defined _GLP_PROB && !defined GLP_PROB
30
#define _GLP_PROB
31
#define GLP_PROB
32
typedef struct { double _opaque_prob; } glp_prob;
33
/* LP/MIP problem object */
34
#endif
35

	
36 28
namespace lemon {
37 29

	
30
  namespace _solver_bits {
31
    class VoidPtr {
32
    private:
33
      void *_ptr;      
34
    public:
35
      VoidPtr() : _ptr(0) {}
36

	
37
      template <typename T>
38
      VoidPtr(T* ptr) : _ptr(reinterpret_cast<void*>(ptr)) {}
39

	
40
      template <typename T>
41
      VoidPtr& operator=(T* ptr) { 
42
        _ptr = reinterpret_cast<void*>(ptr); 
43
        return *this;
44
      }
45

	
46
      template <typename T>
47
      operator T*() const { return reinterpret_cast<T*>(_ptr); }
48
    };
49
  }
38 50

	
39 51
  /// \brief Base interface for the GLPK LP and MIP solver
40 52
  ///
41 53
  /// This class implements the common interface of the GLPK LP and MIP solver.
42 54
  /// \ingroup lp_group
43 55
  class GlpkBase : virtual public LpBase {
44 56
  protected:
45 57

	
46
    typedef glp_prob LPX;
47
    glp_prob* lp;
58
    _solver_bits::VoidPtr lp;
48 59

	
49 60
    GlpkBase();
50 61
    GlpkBase(const GlpkBase&);
51 62
    virtual ~GlpkBase();
52 63

	
53 64
  protected:
54 65

	
55 66
    virtual int _addCol();
56 67
    virtual int _addRow();
57 68

	
58 69
    virtual void _eraseCol(int i);
59 70
    virtual void _eraseRow(int i);
60 71

	
61 72
    virtual void _eraseColId(int i);
62 73
    virtual void _eraseRowId(int i);
63 74

	
64 75
    virtual void _getColName(int col, std::string& name) const;
65 76
    virtual void _setColName(int col, const std::string& name);
66 77
    virtual int _colByName(const std::string& name) const;
67 78

	
68 79
    virtual void _getRowName(int row, std::string& name) const;
69 80
    virtual void _setRowName(int row, const std::string& name);
70 81
    virtual int _rowByName(const std::string& name) const;
71 82

	
72 83
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
73 84
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
74 85

	
75 86
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
76 87
    virtual void _getColCoeffs(int i, InsertIterator b) const;
77 88

	
78 89
    virtual void _setCoeff(int row, int col, Value value);
79 90
    virtual Value _getCoeff(int row, int col) const;
80 91

	
81 92
    virtual void _setColLowerBound(int i, Value value);
82 93
    virtual Value _getColLowerBound(int i) const;
83 94

	
84 95
    virtual void _setColUpperBound(int i, Value value);
85 96
    virtual Value _getColUpperBound(int i) const;
86 97

	
87 98
    virtual void _setRowLowerBound(int i, Value value);
88 99
    virtual Value _getRowLowerBound(int i) const;
89 100

	
90 101
    virtual void _setRowUpperBound(int i, Value value);
91 102
    virtual Value _getRowUpperBound(int i) const;
92 103

	
93 104
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
94 105
    virtual void _getObjCoeffs(InsertIterator b) const;
95 106

	
96 107
    virtual void _setObjCoeff(int i, Value obj_coef);
97 108
    virtual Value _getObjCoeff(int i) const;
98 109

	
99 110
    virtual void _setSense(Sense);
100 111
    virtual Sense _getSense() const;
101 112

	
102 113
    virtual void _clear();
103 114

	
104 115
    virtual void _messageLevel(MessageLevel level);
105 116

	
106 117
  private:
107 118

	
108 119
    static void freeEnv();
109 120

	
110 121
    struct FreeEnvHelper {
111 122
      ~FreeEnvHelper() {
112 123
        freeEnv();
113 124
      }
114 125
    };
115 126
    
116 127
    static FreeEnvHelper freeEnvHelper;
117 128

	
118 129
  protected:
119 130
    
120 131
    int _message_level;
121 132
    
122 133
  public:
123 134

	
124 135
    ///Pointer to the underlying GLPK data structure.
125
    LPX *lpx() {return lp;}
136
    _solver_bits::VoidPtr lpx() {return lp;}
126 137
    ///Const pointer to the underlying GLPK data structure.
127
    const LPX *lpx() const {return lp;}
138
    _solver_bits::VoidPtr lpx() const {return lp;}
128 139

	
129 140
    ///Returns the constraint identifier understood by GLPK.
130 141
    int lpxRow(Row r) const { return rows(id(r)); }
131 142

	
132 143
    ///Returns the variable identifier understood by GLPK.
133 144
    int lpxCol(Col c) const { return cols(id(c)); }
134 145

	
135 146
  };
136 147

	
137 148
  /// \brief Interface for the GLPK LP solver
138 149
  ///
139 150
  /// This class implements an interface for the GLPK LP solver.
140 151
  ///\ingroup lp_group
141 152
  class GlpkLp : public LpSolver, public GlpkBase {
142 153
  public:
143 154

	
144 155
    ///\e
145 156
    GlpkLp();
146 157
    ///\e
147 158
    GlpkLp(const GlpkLp&);
148 159

	
149 160
    ///\e
150 161
    virtual GlpkLp* cloneSolver() const;
151 162
    ///\e
152 163
    virtual GlpkLp* newSolver() const;
153 164

	
154 165
  private:
155 166

	
156 167
    mutable std::vector<double> _primal_ray;
157 168
    mutable std::vector<double> _dual_ray;
158 169

	
159 170
    void _clear_temporals();
160 171

	
161 172
  protected:
162 173

	
163 174
    virtual const char* _solverName() const;
164 175

	
165 176
    virtual SolveExitStatus _solve();
166 177
    virtual Value _getPrimal(int i) const;
167 178
    virtual Value _getDual(int i) const;
168 179

	
169 180
    virtual Value _getPrimalValue() const;
170 181

	
171 182
    virtual VarStatus _getColStatus(int i) const;
172 183
    virtual VarStatus _getRowStatus(int i) const;
173 184

	
174 185
    virtual Value _getPrimalRay(int i) const;
175 186
    virtual Value _getDualRay(int i) const;
Ignore white space 6 line context
... ...
@@ -25,105 +25,105 @@
25 25
#define LEMON_PATH_H
26 26

	
27 27
#include <vector>
28 28
#include <algorithm>
29 29

	
30 30
#include <lemon/error.h>
31 31
#include <lemon/core.h>
32 32
#include <lemon/concepts/path.h>
33 33

	
34 34
namespace lemon {
35 35

	
36 36
  /// \addtogroup paths
37 37
  /// @{
38 38

	
39 39

	
40 40
  /// \brief A structure for representing directed paths in a digraph.
41 41
  ///
42 42
  /// A structure for representing directed path in a digraph.
43 43
  /// \tparam GR The digraph type in which the path is.
44 44
  ///
45 45
  /// In a sense, the path can be treated as a list of arcs. The
46 46
  /// lemon path type stores just this list. As a consequence, it
47 47
  /// cannot enumerate the nodes of the path and the source node of
48 48
  /// a zero length path is undefined.
49 49
  ///
50 50
  /// This implementation is a back and front insertable and erasable
51 51
  /// path type. It can be indexed in O(1) time. The front and back
52 52
  /// insertion and erase is done in O(1) (amortized) time. The
53 53
  /// implementation uses two vectors for storing the front and back
54 54
  /// insertions.
55 55
  template <typename GR>
56 56
  class Path {
57 57
  public:
58 58

	
59 59
    typedef GR Digraph;
60 60
    typedef typename Digraph::Arc Arc;
61 61

	
62 62
    /// \brief Default constructor
63 63
    ///
64 64
    /// Default constructor
65 65
    Path() {}
66 66

	
67 67
    /// \brief Template copy constructor
68 68
    ///
69 69
    /// This constuctor initializes the path from any other path type.
70 70
    /// It simply makes a copy of the given path.
71 71
    template <typename CPath>
72 72
    Path(const CPath& cpath) {
73
      copyPath(*this, cpath);
73
      pathCopy(cpath, *this);
74 74
    }
75 75

	
76 76
    /// \brief Template copy assignment
77 77
    ///
78 78
    /// This operator makes a copy of a path of any other type.
79 79
    template <typename CPath>
80 80
    Path& operator=(const CPath& cpath) {
81
      copyPath(*this, cpath);
81
      pathCopy(cpath, *this);
82 82
      return *this;
83 83
    }
84 84

	
85 85
    /// \brief LEMON style iterator for path arcs
86 86
    ///
87 87
    /// This class is used to iterate on the arcs of the paths.
88 88
    class ArcIt {
89 89
      friend class Path;
90 90
    public:
91 91
      /// \brief Default constructor
92 92
      ArcIt() {}
93 93
      /// \brief Invalid constructor
94 94
      ArcIt(Invalid) : path(0), idx(-1) {}
95 95
      /// \brief Initializate the iterator to the first arc of path
96 96
      ArcIt(const Path &_path)
97 97
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
98 98

	
99 99
    private:
100 100

	
101 101
      ArcIt(const Path &_path, int _idx)
102 102
        : path(&_path), idx(_idx) {}
103 103

	
104 104
    public:
105 105

	
106 106
      /// \brief Conversion to Arc
107 107
      operator const Arc&() const {
108 108
        return path->nth(idx);
109 109
      }
110 110

	
111 111
      /// \brief Next arc
112 112
      ArcIt& operator++() {
113 113
        ++idx;
114 114
        if (idx >= path->length()) idx = -1;
115 115
        return *this;
116 116
      }
117 117

	
118 118
      /// \brief Comparison operator
119 119
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
120 120
      /// \brief Comparison operator
121 121
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
122 122
      /// \brief Comparison operator
123 123
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
124 124

	
125 125
    private:
126 126
      const Path *path;
127 127
      int idx;
128 128
    };
129 129

	
... ...
@@ -213,106 +213,106 @@
213 213
    template <typename CPath>
214 214
    void buildRev(const CPath& path) {
215 215
      int len = path.length();
216 216
      head.reserve(len);
217 217
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
218 218
        head.push_back(it);
219 219
      }
220 220
    }
221 221

	
222 222
  protected:
223 223
    typedef std::vector<Arc> Container;
224 224
    Container head, tail;
225 225

	
226 226
  };
227 227

	
228 228
  /// \brief A structure for representing directed paths in a digraph.
229 229
  ///
230 230
  /// A structure for representing directed path in a digraph.
231 231
  /// \tparam GR The digraph type in which the path is.
232 232
  ///
233 233
  /// In a sense, the path can be treated as a list of arcs. The
234 234
  /// lemon path type stores just this list. As a consequence it
235 235
  /// cannot enumerate the nodes in the path and the zero length paths
236 236
  /// cannot store the source.
237 237
  ///
238 238
  /// This implementation is a just back insertable and erasable path
239 239
  /// type. It can be indexed in O(1) time. The back insertion and
240 240
  /// erasure is amortized O(1) time. This implementation is faster
241 241
  /// then the \c Path type because it use just one vector for the
242 242
  /// arcs.
243 243
  template <typename GR>
244 244
  class SimplePath {
245 245
  public:
246 246

	
247 247
    typedef GR Digraph;
248 248
    typedef typename Digraph::Arc Arc;
249 249

	
250 250
    /// \brief Default constructor
251 251
    ///
252 252
    /// Default constructor
253 253
    SimplePath() {}
254 254

	
255 255
    /// \brief Template copy constructor
256 256
    ///
257 257
    /// This path can be initialized with any other path type. It just
258 258
    /// makes a copy of the given path.
259 259
    template <typename CPath>
260 260
    SimplePath(const CPath& cpath) {
261
      copyPath(*this, cpath);
261
      pathCopy(cpath, *this);
262 262
    }
263 263

	
264 264
    /// \brief Template copy assignment
265 265
    ///
266 266
    /// This path can be initialized with any other path type. It just
267 267
    /// makes a copy of the given path.
268 268
    template <typename CPath>
269 269
    SimplePath& operator=(const CPath& cpath) {
270
      copyPath(*this, cpath);
270
      pathCopy(cpath, *this);
271 271
      return *this;
272 272
    }
273 273

	
274 274
    /// \brief Iterator class to iterate on the arcs of the paths
275 275
    ///
276 276
    /// This class is used to iterate on the arcs of the paths
277 277
    ///
278 278
    /// Of course it converts to Digraph::Arc
279 279
    class ArcIt {
280 280
      friend class SimplePath;
281 281
    public:
282 282
      /// Default constructor
283 283
      ArcIt() {}
284 284
      /// Invalid constructor
285 285
      ArcIt(Invalid) : path(0), idx(-1) {}
286 286
      /// \brief Initializate the constructor to the first arc of path
287 287
      ArcIt(const SimplePath &_path)
288 288
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
289 289

	
290 290
    private:
291 291

	
292 292
      /// Constructor with starting point
293 293
      ArcIt(const SimplePath &_path, int _idx)
294 294
        : idx(_idx), path(&_path) {}
295 295

	
296 296
    public:
297 297

	
298 298
      ///Conversion to Digraph::Arc
299 299
      operator const Arc&() const {
300 300
        return path->nth(idx);
301 301
      }
302 302

	
303 303
      /// Next arc
304 304
      ArcIt& operator++() {
305 305
        ++idx;
306 306
        if (idx >= path->length()) idx = -1;
307 307
        return *this;
308 308
      }
309 309

	
310 310
      /// Comparison operator
311 311
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
312 312
      /// Comparison operator
313 313
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
314 314
      /// Comparison operator
315 315
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
316 316

	
317 317
    private:
318 318
      const SimplePath *path;
... ...
@@ -392,113 +392,113 @@
392 392
  /// \brief A structure for representing directed paths in a digraph.
393 393
  ///
394 394
  /// A structure for representing directed path in a digraph.
395 395
  /// \tparam GR The digraph type in which the path is.
396 396
  ///
397 397
  /// In a sense, the path can be treated as a list of arcs. The
398 398
  /// lemon path type stores just this list. As a consequence it
399 399
  /// cannot enumerate the nodes in the path and the zero length paths
400 400
  /// cannot store the source.
401 401
  ///
402 402
  /// This implementation is a back and front insertable and erasable
403 403
  /// path type. It can be indexed in O(k) time, where k is the rank
404 404
  /// of the arc in the path. The length can be computed in O(n)
405 405
  /// time. The front and back insertion and erasure is O(1) time
406 406
  /// and it can be splited and spliced in O(1) time.
407 407
  template <typename GR>
408 408
  class ListPath {
409 409
  public:
410 410

	
411 411
    typedef GR Digraph;
412 412
    typedef typename Digraph::Arc Arc;
413 413

	
414 414
  protected:
415 415

	
416 416
    // the std::list<> is incompatible
417 417
    // hard to create invalid iterator
418 418
    struct Node {
419 419
      Arc arc;
420 420
      Node *next, *prev;
421 421
    };
422 422

	
423 423
    Node *first, *last;
424 424

	
425 425
    std::allocator<Node> alloc;
426 426

	
427 427
  public:
428 428

	
429 429
    /// \brief Default constructor
430 430
    ///
431 431
    /// Default constructor
432 432
    ListPath() : first(0), last(0) {}
433 433

	
434 434
    /// \brief Template copy constructor
435 435
    ///
436 436
    /// This path can be initialized with any other path type. It just
437 437
    /// makes a copy of the given path.
438 438
    template <typename CPath>
439 439
    ListPath(const CPath& cpath) : first(0), last(0) {
440
      copyPath(*this, cpath);
440
      pathCopy(cpath, *this);
441 441
    }
442 442

	
443 443
    /// \brief Destructor of the path
444 444
    ///
445 445
    /// Destructor of the path
446 446
    ~ListPath() {
447 447
      clear();
448 448
    }
449 449

	
450 450
    /// \brief Template copy assignment
451 451
    ///
452 452
    /// This path can be initialized with any other path type. It just
453 453
    /// makes a copy of the given path.
454 454
    template <typename CPath>
455 455
    ListPath& operator=(const CPath& cpath) {
456
      copyPath(*this, cpath);
456
      pathCopy(cpath, *this);
457 457
      return *this;
458 458
    }
459 459

	
460 460
    /// \brief Iterator class to iterate on the arcs of the paths
461 461
    ///
462 462
    /// This class is used to iterate on the arcs of the paths
463 463
    ///
464 464
    /// Of course it converts to Digraph::Arc
465 465
    class ArcIt {
466 466
      friend class ListPath;
467 467
    public:
468 468
      /// Default constructor
469 469
      ArcIt() {}
470 470
      /// Invalid constructor
471 471
      ArcIt(Invalid) : path(0), node(0) {}
472 472
      /// \brief Initializate the constructor to the first arc of path
473 473
      ArcIt(const ListPath &_path)
474 474
        : path(&_path), node(_path.first) {}
475 475

	
476 476
    protected:
477 477

	
478 478
      ArcIt(const ListPath &_path, Node *_node)
479 479
        : path(&_path), node(_node) {}
480 480

	
481 481

	
482 482
    public:
483 483

	
484 484
      ///Conversion to Digraph::Arc
485 485
      operator const Arc&() const {
486 486
        return node->arc;
487 487
      }
488 488

	
489 489
      /// Next arc
490 490
      ArcIt& operator++() {
491 491
        node = node->next;
492 492
        return *this;
493 493
      }
494 494

	
495 495
      /// Comparison operator
496 496
      bool operator==(const ArcIt& e) const { return node==e.node; }
497 497
      /// Comparison operator
498 498
      bool operator!=(const ArcIt& e) const { return node!=e.node; }
499 499
      /// Comparison operator
500 500
      bool operator<(const ArcIt& e) const { return node<e.node; }
501 501

	
502 502
    private:
503 503
      const ListPath *path;
504 504
      Node *node;
... ...
@@ -718,113 +718,113 @@
718 718
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
719 719
        addBack(it);
720 720
      }
721 721
    }
722 722

	
723 723
    template <typename CPath>
724 724
    void buildRev(const CPath& path) {
725 725
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
726 726
        addFront(it);
727 727
      }
728 728
    }
729 729

	
730 730
  };
731 731

	
732 732
  /// \brief A structure for representing directed paths in a digraph.
733 733
  ///
734 734
  /// A structure for representing directed path in a digraph.
735 735
  /// \tparam GR The digraph type in which the path is.
736 736
  ///
737 737
  /// In a sense, the path can be treated as a list of arcs. The
738 738
  /// lemon path type stores just this list. As a consequence it
739 739
  /// cannot enumerate the nodes in the path and the source node of
740 740
  /// a zero length path is undefined.
741 741
  ///
742 742
  /// This implementation is completly static, i.e. it can be copy constucted
743 743
  /// or copy assigned from another path, but otherwise it cannot be
744 744
  /// modified.
745 745
  ///
746 746
  /// Being the the most memory efficient path type in LEMON,
747 747
  /// it is intented to be
748 748
  /// used when you want to store a large number of paths.
749 749
  template <typename GR>
750 750
  class StaticPath {
751 751
  public:
752 752

	
753 753
    typedef GR Digraph;
754 754
    typedef typename Digraph::Arc Arc;
755 755

	
756 756
    /// \brief Default constructor
757 757
    ///
758 758
    /// Default constructor
759 759
    StaticPath() : len(0), arcs(0) {}
760 760

	
761 761
    /// \brief Template copy constructor
762 762
    ///
763 763
    /// This path can be initialized from any other path type.
764 764
    template <typename CPath>
765 765
    StaticPath(const CPath& cpath) : arcs(0) {
766
      copyPath(*this, cpath);
766
      pathCopy(cpath, *this);
767 767
    }
768 768

	
769 769
    /// \brief Destructor of the path
770 770
    ///
771 771
    /// Destructor of the path
772 772
    ~StaticPath() {
773 773
      if (arcs) delete[] arcs;
774 774
    }
775 775

	
776 776
    /// \brief Template copy assignment
777 777
    ///
778 778
    /// This path can be made equal to any other path type. It simply
779 779
    /// makes a copy of the given path.
780 780
    template <typename CPath>
781 781
    StaticPath& operator=(const CPath& cpath) {
782
      copyPath(*this, cpath);
782
      pathCopy(cpath, *this);
783 783
      return *this;
784 784
    }
785 785

	
786 786
    /// \brief Iterator class to iterate on the arcs of the paths
787 787
    ///
788 788
    /// This class is used to iterate on the arcs of the paths
789 789
    ///
790 790
    /// Of course it converts to Digraph::Arc
791 791
    class ArcIt {
792 792
      friend class StaticPath;
793 793
    public:
794 794
      /// Default constructor
795 795
      ArcIt() {}
796 796
      /// Invalid constructor
797 797
      ArcIt(Invalid) : path(0), idx(-1) {}
798 798
      /// Initializate the constructor to the first arc of path
799 799
      ArcIt(const StaticPath &_path)
800 800
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
801 801

	
802 802
    private:
803 803

	
804 804
      /// Constructor with starting point
805 805
      ArcIt(const StaticPath &_path, int _idx)
806 806
        : idx(_idx), path(&_path) {}
807 807

	
808 808
    public:
809 809

	
810 810
      ///Conversion to Digraph::Arc
811 811
      operator const Arc&() const {
812 812
        return path->nth(idx);
813 813
      }
814 814

	
815 815
      /// Next arc
816 816
      ArcIt& operator++() {
817 817
        ++idx;
818 818
        if (idx >= path->length()) idx = -1;
819 819
        return *this;
820 820
      }
821 821

	
822 822
      /// Comparison operator
823 823
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
824 824
      /// Comparison operator
825 825
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
826 826
      /// Comparison operator
827 827
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
828 828

	
829 829
    private:
830 830
      const StaticPath *path;
... ...
@@ -883,195 +883,205 @@
883 883
    template <typename CPath>
884 884
    void buildRev(const CPath& path) {
885 885
      len = path.length();
886 886
      arcs = new Arc[len];
887 887
      int index = len;
888 888
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
889 889
        --index;
890 890
        arcs[index] = it;
891 891
      }
892 892
    }
893 893

	
894 894
  private:
895 895
    int len;
896 896
    Arc* arcs;
897 897
  };
898 898

	
899 899
  ///////////////////////////////////////////////////////////////////////
900 900
  // Additional utilities
901 901
  ///////////////////////////////////////////////////////////////////////
902 902

	
903 903
  namespace _path_bits {
904 904

	
905 905
    template <typename Path, typename Enable = void>
906 906
    struct RevPathTagIndicator {
907 907
      static const bool value = false;
908 908
    };
909 909

	
910 910
    template <typename Path>
911 911
    struct RevPathTagIndicator<
912 912
      Path,
913 913
      typename enable_if<typename Path::RevPathTag, void>::type
914 914
      > {
915 915
      static const bool value = true;
916 916
    };
917 917

	
918 918
    template <typename Path, typename Enable = void>
919 919
    struct BuildTagIndicator {
920 920
      static const bool value = false;
921 921
    };
922 922

	
923 923
    template <typename Path>
924 924
    struct BuildTagIndicator<
925 925
      Path,
926 926
      typename enable_if<typename Path::BuildTag, void>::type
927 927
    > {
928 928
      static const bool value = true;
929 929
    };
930 930

	
931
    template <typename Target, typename Source,
932
              bool buildEnable = BuildTagIndicator<Target>::value>
931
    template <typename From, typename To,
932
              bool buildEnable = BuildTagIndicator<To>::value>
933 933
    struct PathCopySelectorForward {
934
      static void copy(Target& target, const Source& source) {
935
        target.clear();
936
        for (typename Source::ArcIt it(source); it != INVALID; ++it) {
937
          target.addBack(it);
934
      static void copy(const From& from, To& to) {
935
        to.clear();
936
        for (typename From::ArcIt it(from); it != INVALID; ++it) {
937
          to.addBack(it);
938 938
        }
939 939
      }
940 940
    };
941 941

	
942
    template <typename Target, typename Source>
943
    struct PathCopySelectorForward<Target, Source, true> {
944
      static void copy(Target& target, const Source& source) {
945
        target.clear();
946
        target.build(source);
942
    template <typename From, typename To>
943
    struct PathCopySelectorForward<From, To, true> {
944
      static void copy(const From& from, To& to) {
945
        to.clear();
946
        to.build(from);
947 947
      }
948 948
    };
949 949

	
950
    template <typename Target, typename Source,
951
              bool buildEnable = BuildTagIndicator<Target>::value>
950
    template <typename From, typename To,
951
              bool buildEnable = BuildTagIndicator<To>::value>
952 952
    struct PathCopySelectorBackward {
953
      static void copy(Target& target, const Source& source) {
954
        target.clear();
955
        for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
956
          target.addFront(it);
953
      static void copy(const From& from, To& to) {
954
        to.clear();
955
        for (typename From::RevArcIt it(from); it != INVALID; ++it) {
956
          to.addFront(it);
957 957
        }
958 958
      }
959 959
    };
960 960

	
961
    template <typename Target, typename Source>
962
    struct PathCopySelectorBackward<Target, Source, true> {
963
      static void copy(Target& target, const Source& source) {
964
        target.clear();
965
        target.buildRev(source);
961
    template <typename From, typename To>
962
    struct PathCopySelectorBackward<From, To, true> {
963
      static void copy(const From& from, To& to) {
964
        to.clear();
965
        to.buildRev(from);
966 966
      }
967 967
    };
968 968

	
969 969
    
970
    template <typename Target, typename Source,
971
              bool revEnable = RevPathTagIndicator<Source>::value>
970
    template <typename From, typename To,
971
              bool revEnable = RevPathTagIndicator<From>::value>
972 972
    struct PathCopySelector {
973
      static void copy(Target& target, const Source& source) {
974
        PathCopySelectorForward<Target, Source>::copy(target, source);
973
      static void copy(const From& from, To& to) {
974
        PathCopySelectorForward<From, To>::copy(from, to);
975 975
      }      
976 976
    };
977 977

	
978
    template <typename Target, typename Source>
979
    struct PathCopySelector<Target, Source, true> {
980
      static void copy(Target& target, const Source& source) {
981
        PathCopySelectorBackward<Target, Source>::copy(target, source);
978
    template <typename From, typename To>
979
    struct PathCopySelector<From, To, true> {
980
      static void copy(const From& from, To& to) {
981
        PathCopySelectorBackward<From, To>::copy(from, to);
982 982
      }      
983 983
    };
984 984

	
985 985
  }
986 986

	
987 987

	
988 988
  /// \brief Make a copy of a path.
989 989
  ///
990
  ///  This function makes a copy of a path.
991
  template <typename Target, typename Source>
992
  void copyPath(Target& target, const Source& source) {
993
    checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
994
    _path_bits::PathCopySelector<Target, Source>::copy(target, source);
990
  /// This function makes a copy of a path.
991
  template <typename From, typename To>
992
  void pathCopy(const From& from, To& to) {
993
    checkConcept<concepts::PathDumper<typename From::Digraph>, From>();
994
    _path_bits::PathCopySelector<From, To>::copy(from, to);
995
  }
996

	
997
  /// \brief Deprecated version of \ref pathCopy().
998
  ///
999
  /// Deprecated version of \ref pathCopy() (only for reverse compatibility).
1000
  template <typename To, typename From>
1001
  void copyPath(To& to, const From& from) {
1002
    pathCopy(from, to);
995 1003
  }
996 1004

	
997 1005
  /// \brief Check the consistency of a path.
998 1006
  ///
999 1007
  /// This function checks that the target of each arc is the same
1000 1008
  /// as the source of the next one.
1001 1009
  ///
1002 1010
  template <typename Digraph, typename Path>
1003 1011
  bool checkPath(const Digraph& digraph, const Path& path) {
1004 1012
    typename Path::ArcIt it(path);
1005 1013
    if (it == INVALID) return true;
1006 1014
    typename Digraph::Node node = digraph.target(it);
1007 1015
    ++it;
1008 1016
    while (it != INVALID) {
1009 1017
      if (digraph.source(it) != node) return false;
1010 1018
      node = digraph.target(it);
1011 1019
      ++it;
1012 1020
    }
1013 1021
    return true;
1014 1022
  }
1015 1023

	
1016 1024
  /// \brief The source of a path
1017 1025
  ///
1018
  /// This function returns the source of the given path.
1026
  /// This function returns the source node of the given path.
1027
  /// If the path is empty, then it returns \c INVALID.
1019 1028
  template <typename Digraph, typename Path>
1020 1029
  typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
1021
    return digraph.source(path.front());
1030
    return path.empty() ? INVALID : digraph.source(path.front());
1022 1031
  }
1023 1032

	
1024 1033
  /// \brief The target of a path
1025 1034
  ///
1026
  /// This function returns the target of the given path.
1035
  /// This function returns the target node of the given path.
1036
  /// If the path is empty, then it returns \c INVALID.
1027 1037
  template <typename Digraph, typename Path>
1028 1038
  typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1029
    return digraph.target(path.back());
1039
    return path.empty() ? INVALID : digraph.target(path.back());
1030 1040
  }
1031 1041

	
1032 1042
  /// \brief Class which helps to iterate through the nodes of a path
1033 1043
  ///
1034 1044
  /// In a sense, the path can be treated as a list of arcs. The
1035 1045
  /// lemon path type stores only this list. As a consequence, it
1036 1046
  /// cannot enumerate the nodes in the path and the zero length paths
1037 1047
  /// cannot have a source node.
1038 1048
  ///
1039 1049
  /// This class implements the node iterator of a path structure. To
1040 1050
  /// provide this feature, the underlying digraph should be passed to
1041 1051
  /// the constructor of the iterator.
1042 1052
  template <typename Path>
1043 1053
  class PathNodeIt {
1044 1054
  private:
1045 1055
    const typename Path::Digraph *_digraph;
1046 1056
    typename Path::ArcIt _it;
1047 1057
    typename Path::Digraph::Node _nd;
1048 1058

	
1049 1059
  public:
1050 1060

	
1051 1061
    typedef typename Path::Digraph Digraph;
1052 1062
    typedef typename Digraph::Node Node;
1053 1063

	
1054 1064
    /// Default constructor
1055 1065
    PathNodeIt() {}
1056 1066
    /// Invalid constructor
1057 1067
    PathNodeIt(Invalid)
1058 1068
      : _digraph(0), _it(INVALID), _nd(INVALID) {}
1059 1069
    /// Constructor
1060 1070
    PathNodeIt(const Digraph& digraph, const Path& path)
1061 1071
      : _digraph(&digraph), _it(path) {
1062 1072
      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1063 1073
    }
1064 1074
    /// Constructor
1065 1075
    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1066 1076
      : _digraph(&digraph), _it(path), _nd(src) {}
1067 1077

	
1068 1078
    ///Conversion to Digraph::Node
1069 1079
    operator Node() const {
1070 1080
      return _nd;
1071 1081
    }
1072 1082

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

	
19 19
#include <iostream>
20 20
#include <fstream>
21 21
#include <string>
22 22
#include <vector>
23 23

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

	
27 27
#include <lemon/smart_graph.h>
28 28

	
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

	
40 43
typedef ListDigraph Digraph;
41 44
DIGRAPH_TYPEDEFS(Digraph);
42 45

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

	
81 84
int test_seq[] = { 2, 28, 19, 27, 33, 25, 13, 41, 10, 26,  1,  9,  4, 34};
... ...
@@ -138,50 +141,84 @@
138 141

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

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

	
157 160
}
158 161

	
159 162
int main() {
160 163

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

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

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

	
175 178
  {
176 179
    typedef BinHeap<Prio, ItemIntMap> IntHeap;
177 180
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
178 181
    heapSortTest<IntHeap>();
179 182
    heapIncreaseTest<IntHeap>();
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
}
0 comments (0 inline)