[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