[Lemon-commits] Balazs Dezso: Simplified implementation of bucke...
Lemon HG
hg at lemon.cs.elte.hu
Thu Jun 25 14:55:59 CEST 2009
details: http://lemon.cs.elte.hu/hg/lemon/rev/bb8c4cd57900
changeset: 730:bb8c4cd57900
user: Balazs Dezso <deba [at] inf.elte.hu>
date: Thu Jun 11 22:16:11 2009 +0200
description:
Simplified implementation of bucket heaps (#50)
diffstat:
lemon/bucket_heap.h | 368 +++++++---------------------------------------------
1 files changed, 51 insertions(+), 317 deletions(-)
diffs (truncated from 491 to 300 lines):
diff --git a/lemon/bucket_heap.h b/lemon/bucket_heap.h
--- a/lemon/bucket_heap.h
+++ b/lemon/bucket_heap.h
@@ -29,6 +29,30 @@
namespace lemon {
+ namespace _bucket_heap_bits {
+
+ template <bool minimize>
+ struct DirectionTraits {
+ static bool less(int left, int right) {
+ return left < right;
+ }
+ static void increase(int& value) {
+ ++value;
+ }
+ };
+
+ template <>
+ struct DirectionTraits<false> {
+ static bool less(int left, int right) {
+ return left > right;
+ }
+ static void increase(int& value) {
+ --value;
+ }
+ };
+
+ }
+
/// \ingroup auxdat
///
/// \brief A Bucket Heap implementation.
@@ -45,7 +69,7 @@
/// to handle the cross references.
/// \param minimize If the given parameter is true then the heap gives back
/// the lowest priority.
- template <typename _ItemIntMap, bool minimize = true >
+ template <typename _ItemIntMap, bool minimize = true>
class BucketHeap {
public:
@@ -58,6 +82,12 @@
/// \e
typedef _ItemIntMap ItemIntMap;
+ private:
+
+ typedef _bucket_heap_bits::DirectionTraits<minimize> Direction;
+
+ public:
+
/// \brief Type to represent the items states.
///
/// Each Item element have a state associated to it. It may be "in heap",
@@ -161,7 +191,7 @@
index[i] = idx;
data.push_back(BucketItem(i, p));
lace(idx);
- if (p < minimal) {
+ if (Direction::less(p, minimal)) {
minimal = p;
}
}
@@ -172,7 +202,7 @@
/// \pre The heap must be nonempty.
Item top() const {
while (first[minimal] == -1) {
- ++minimal;
+ Direction::increase(minimal);
}
return data[first[minimal]].item;
}
@@ -183,7 +213,7 @@
/// \pre The heap must be nonempty.
Prio prio() const {
while (first[minimal] == -1) {
- ++minimal;
+ Direction::increase(minimal);
}
return minimal;
}
@@ -194,7 +224,7 @@
/// \pre The heap must be non-empty.
void pop() {
while (first[minimal] == -1) {
- ++minimal;
+ Direction::increase(minimal);
}
int idx = first[minimal];
index[data[idx].item] = -2;
@@ -235,11 +265,11 @@
void set(const Item &i, const Prio &p) {
int idx = index[i];
if (idx < 0) {
- push(i,p);
- } else if (p > data[idx].value) {
+ push(i, p);
+ } else if (Direction::less(p, data[idx].value)) {
+ decrease(i, p);
+ } else {
increase(i, p);
- } else {
- decrease(i, p);
}
}
@@ -254,7 +284,7 @@
int idx = index[i];
unlace(idx);
data[idx].value = p;
- if (p < minimal) {
+ if (Direction::less(p, minimal)) {
minimal = p;
}
lace(idx);
@@ -328,193 +358,6 @@
}; // class BucketHeap
-
- template <typename _ItemIntMap>
- class BucketHeap<_ItemIntMap, false> {
-
- public:
- typedef typename _ItemIntMap::Key Item;
- typedef int Prio;
- typedef std::pair<Item, Prio> Pair;
- typedef _ItemIntMap ItemIntMap;
-
- enum State {
- IN_HEAP = 0,
- PRE_HEAP = -1,
- POST_HEAP = -2
- };
-
- public:
-
- explicit BucketHeap(ItemIntMap &_index) : index(_index), maximal(-1) {}
-
- int size() const { return data.size(); }
- bool empty() const { return data.empty(); }
-
- void clear() {
- data.clear(); first.clear(); maximal = -1;
- }
-
- private:
-
- void relocate_last(int idx) {
- if (idx + 1 != int(data.size())) {
- data[idx] = data.back();
- if (data[idx].prev != -1) {
- data[data[idx].prev].next = idx;
- } else {
- first[data[idx].value] = idx;
- }
- if (data[idx].next != -1) {
- data[data[idx].next].prev = idx;
- }
- index[data[idx].item] = idx;
- }
- data.pop_back();
- }
-
- void unlace(int idx) {
- if (data[idx].prev != -1) {
- data[data[idx].prev].next = data[idx].next;
- } else {
- first[data[idx].value] = data[idx].next;
- }
- if (data[idx].next != -1) {
- data[data[idx].next].prev = data[idx].prev;
- }
- }
-
- void lace(int idx) {
- if (int(first.size()) <= data[idx].value) {
- first.resize(data[idx].value + 1, -1);
- }
- data[idx].next = first[data[idx].value];
- if (data[idx].next != -1) {
- data[data[idx].next].prev = idx;
- }
- first[data[idx].value] = idx;
- data[idx].prev = -1;
- }
-
- public:
-
- void push(const Pair& p) {
- push(p.first, p.second);
- }
-
- void push(const Item &i, const Prio &p) {
- int idx = data.size();
- index[i] = idx;
- data.push_back(BucketItem(i, p));
- lace(idx);
- if (data[idx].value > maximal) {
- maximal = data[idx].value;
- }
- }
-
- Item top() const {
- while (first[maximal] == -1) {
- --maximal;
- }
- return data[first[maximal]].item;
- }
-
- Prio prio() const {
- while (first[maximal] == -1) {
- --maximal;
- }
- return maximal;
- }
-
- void pop() {
- while (first[maximal] == -1) {
- --maximal;
- }
- int idx = first[maximal];
- index[data[idx].item] = -2;
- unlace(idx);
- relocate_last(idx);
- }
-
- void erase(const Item &i) {
- int idx = index[i];
- index[data[idx].item] = -2;
- unlace(idx);
- relocate_last(idx);
- }
-
- Prio operator[](const Item &i) const {
- int idx = index[i];
- return data[idx].value;
- }
-
- void set(const Item &i, const Prio &p) {
- int idx = index[i];
- if (idx < 0) {
- push(i,p);
- } else if (p > data[idx].value) {
- decrease(i, p);
- } else {
- increase(i, p);
- }
- }
-
- void decrease(const Item &i, const Prio &p) {
- int idx = index[i];
- unlace(idx);
- data[idx].value = p;
- if (p > maximal) {
- maximal = p;
- }
- lace(idx);
- }
-
- void increase(const Item &i, const Prio &p) {
- int idx = index[i];
- unlace(idx);
- data[idx].value = p;
- lace(idx);
- }
-
- State state(const Item &i) const {
- int idx = index[i];
- if (idx >= 0) idx = 0;
- return State(idx);
- }
-
- void state(const Item& i, State st) {
- switch (st) {
- case POST_HEAP:
- case PRE_HEAP:
- if (state(i) == IN_HEAP) {
- erase(i);
- }
- index[i] = st;
- break;
- case IN_HEAP:
- break;
- }
- }
-
- private:
-
- struct BucketItem {
- BucketItem(const Item& _item, int _value)
- : item(_item), value(_value) {}
-
- Item item;
- int value;
-
- int prev, next;
- };
More information about the Lemon-commits
mailing list