[Lemon-commits] Peter Kovacs: Add fourary, k-ary, pairing and bi...

Lemon HG hg at lemon.cs.elte.hu
Mon Aug 31 12:21:04 CEST 2009


details:   http://lemon.cs.elte.hu/hg/lemon/rev/d1a9224f1e30
changeset: 754:d1a9224f1e30
user:      Peter Kovacs <kpeter [at] inf.elte.hu>
date:      Thu Jul 09 02:38:01 2009 +0200
description:
	Add fourary, k-ary, pairing and binomial heaps (#301) These
	structures were implemented by Dorian Batha.

diffstat:

 lemon/Makefile.am    |    4 +
 lemon/binom_heap.h   |  506 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lemon/fourary_heap.h |  350 +++++++++++++++++++++++++++++++++++
 lemon/kary_heap.h    |  342 ++++++++++++++++++++++++++++++++++
 lemon/pairing_heap.h |  469 ++++++++++++++++++++++++++++++++++++++++++++++
 test/heap_test.cc    |   74 ++++++-
 6 files changed, 1734 insertions(+), 11 deletions(-)

diffs (truncated from 1896 to 300 lines):

diff --git a/lemon/Makefile.am b/lemon/Makefile.am
--- a/lemon/Makefile.am
+++ b/lemon/Makefile.am
@@ -59,6 +59,7 @@
 	lemon/assert.h \
 	lemon/bfs.h \
 	lemon/bin_heap.h \
+	lemon/binom_heap.h \
 	lemon/bucket_heap.h \
 	lemon/cbc.h \
 	lemon/circulation.h \
@@ -78,12 +79,14 @@
 	lemon/error.h \
 	lemon/euler.h \
 	lemon/fib_heap.h \
+	lemon/fourary_heap.h \
 	lemon/full_graph.h \
 	lemon/glpk.h \
 	lemon/gomory_hu.h \
 	lemon/graph_to_eps.h \
 	lemon/grid_graph.h \
 	lemon/hypercube_graph.h \
+	lemon/kary_heap.h \
 	lemon/kruskal.h \
 	lemon/hao_orlin.h \
 	lemon/lgf_reader.h \
@@ -99,6 +102,7 @@
 	lemon/min_cost_arborescence.h \
 	lemon/nauty_reader.h \
 	lemon/network_simplex.h \
+	lemon/pairing_heap.h \
 	lemon/path.h \
 	lemon/preflow.h \
 	lemon/radix_heap.h \
diff --git a/lemon/binom_heap.h b/lemon/binom_heap.h
new file mode 100644
--- /dev/null
+++ b/lemon/binom_heap.h
@@ -0,0 +1,506 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BINOM_HEAP_H
+#define LEMON_BINOM_HEAP_H
+
+///\file
+///\ingroup auxdat
+///\brief Binomial Heap implementation.
+
+#include <vector>
+#include <functional>
+#include <lemon/math.h>
+#include <lemon/counter.h>
+
+namespace lemon {
+
+  /// \ingroup auxdat
+  ///
+  ///\brief Binomial Heap.
+  ///
+  ///This class implements the \e Binomial \e heap data structure. A \e heap
+  ///is a data structure for storing items with specified values called \e
+  ///priorities in such a way that finding the item with minimum priority is
+  ///efficient. \c Compare specifies the ordering of the priorities. In a heap
+  ///one can change the priority of an item, add or erase an item, etc.
+  ///
+  ///The methods \ref increase and \ref erase are not efficient in a Binomial
+  ///heap. In case of many calls to these operations, it is better to use a
+  ///\ref BinHeap "binary heap".
+  ///
+  ///\param _Prio Type of the priority of the items.
+  ///\param _ItemIntMap A read and writable Item int map, used internally
+  ///to handle the cross references.
+  ///\param _Compare A class for the ordering of the priorities. The
+  ///default is \c std::less<_Prio>.
+  ///
+  ///\sa BinHeap
+  ///\sa Dijkstra
+  ///\author Dorian Batha
+
+#ifdef DOXYGEN
+  template <typename _Prio,
+            typename _ItemIntMap,
+            typename _Compare>
+#else
+  template <typename _Prio,
+            typename _ItemIntMap,
+            typename _Compare = std::less<_Prio> >
+#endif
+  class BinomHeap {
+  public:
+    typedef _ItemIntMap ItemIntMap;
+    typedef _Prio Prio;
+    typedef typename ItemIntMap::Key Item;
+    typedef std::pair<Item,Prio> Pair;
+    typedef _Compare Compare;
+
+  private:
+    class store;
+
+    std::vector<store> container;
+    int minimum, head;
+    ItemIntMap &iimap;
+    Compare comp;
+    int num_items;
+
+  public:
+    ///Status of the nodes
+    enum State {
+      ///The node is in the heap
+      IN_HEAP = 0,
+      ///The node has never been in the heap
+      PRE_HEAP = -1,
+      ///The node was in the heap but it got out of it
+      POST_HEAP = -2
+    };
+
+    /// \brief The constructor
+    ///
+    /// \c _iimap should be given to the constructor, since it is
+    ///   used internally to handle the cross references.
+    explicit BinomHeap(ItemIntMap &_iimap)
+      : minimum(0), head(-1), iimap(_iimap), num_items() {}
+
+    /// \brief The constructor
+    ///
+    /// \c _iimap should be given to the constructor, since it is used
+    /// internally to handle the cross references. \c _comp is an
+    /// object for ordering of the priorities.
+    BinomHeap(ItemIntMap &_iimap, const Compare &_comp)
+      : minimum(0), head(-1), iimap(_iimap), comp(_comp), num_items() {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// Returns the number of items stored in the heap.
+    int size() const { return num_items; }
+
+    /// \brief Checks if the heap stores no items.
+    ///
+    ///   Returns \c true if and only if the heap stores no items.
+    bool empty() const { return num_items==0; }
+
+    /// \brief Make empty this heap.
+    ///
+    /// Make empty this heap. It does not change the cross reference
+    /// map.  If you want to reuse a heap what is not surely empty you
+    /// should first clear the heap and after that you should set the
+    /// cross reference map for each item to \c PRE_HEAP.
+    void clear() {
+      container.clear(); minimum=0; num_items=0; head=-1;
+    }
+
+    /// \brief \c item gets to the heap with priority \c value independently
+    /// if \c item was already there.
+    ///
+    /// This method calls \ref push(\c item, \c value) if \c item is not
+    /// stored in the heap and it calls \ref decrease(\c item, \c value) or
+    /// \ref increase(\c item, \c value) otherwise.
+    void set (const Item& item, const Prio& value) {
+      int i=iimap[item];
+      if ( i >= 0 && container[i].in ) {
+        if ( comp(value, container[i].prio) ) decrease(item, value);
+        if ( comp(container[i].prio, value) ) increase(item, value);
+      } else push(item, value);
+    }
+
+    /// \brief Adds \c item to the heap with priority \c value.
+    ///
+    /// Adds \c item to the heap with priority \c value.
+    /// \pre \c item must not be stored in the heap.
+    void push (const Item& item, const Prio& value) {
+      int i=iimap[item];
+      if ( i<0 ) {
+        int s=container.size();
+        iimap.set( item,s );
+        store st;
+        st.name=item;
+        container.push_back(st);
+        i=s;
+      }
+      else {
+        container[i].parent=container[i].right_neighbor=container[i].child=-1;
+        container[i].degree=0;
+        container[i].in=true;
+      }
+      container[i].prio=value;
+
+      if( 0==num_items ) { head=i; minimum=i; }
+      else { merge(i); }
+
+      minimum = find_min();
+
+      ++num_items;
+    }
+
+    /// \brief Returns the item with minimum priority relative to \c Compare.
+    ///
+    /// This method returns the item with minimum priority relative to \c
+    /// Compare.
+    /// \pre The heap must be nonempty.
+    Item top() const { return container[minimum].name; }
+
+    /// \brief Returns the minimum priority relative to \c Compare.
+    ///
+    /// It returns the minimum priority relative to \c Compare.
+    /// \pre The heap must be nonempty.
+    const Prio& prio() const { return container[minimum].prio; }
+
+    /// \brief Returns the priority of \c item.
+    ///
+    /// It returns the priority of \c item.
+    /// \pre \c item must be in the heap.
+    const Prio& operator[](const Item& item) const {
+      return container[iimap[item]].prio;
+    }
+
+    /// \brief Deletes the item with minimum priority relative to \c Compare.
+    ///
+    /// This method deletes the item with minimum priority relative to \c
+    /// Compare from the heap.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      container[minimum].in=false;
+
+      int head_child=-1;
+      if ( container[minimum].child!=-1 ) {
+        int child=container[minimum].child;
+        int neighb;
+        int prev=-1;
+        while( child!=-1 ) {
+          neighb=container[child].right_neighbor;
+          container[child].parent=-1;
+          container[child].right_neighbor=prev;
+          head_child=child;
+          prev=child;
+          child=neighb;
+        }
+      }
+
+      // The first case is that there are only one root.
+      if ( -1==container[head].right_neighbor ) {
+        head=head_child;
+      }
+      // The case where there are more roots.
+      else {
+        if( head!=minimum )  { unlace(minimum); }
+        else { head=container[head].right_neighbor; }
+
+        merge(head_child);
+      }
+      minimum=find_min();
+      --num_items;
+    }
+
+    /// \brief Deletes \c item from the heap.
+    ///
+    /// This method deletes \c item from the heap, if \c item was already
+    /// stored in the heap. It is quite inefficient in Binomial heaps.
+    void erase (const Item& item) {
+      int i=iimap[item];
+      if ( i >= 0 && container[i].in ) {
+        decrease( item, container[minimum].prio-1 );
+        pop();
+      }
+    }
+
+    /// \brief Decreases the priority of \c item to \c value.
+    ///
+    /// This method decreases the priority of \c item to \c value.
+    /// \pre \c item must be stored in the heap with priority at least \c
+    ///   value relative to \c Compare.
+    void decrease (Item item, const Prio& value) {
+      int i=iimap[item];
+
+      if( comp( value,container[i].prio ) ) {
+        container[i].prio=value;
+
+        int p_loc=container[i].parent, loc=i;
+        int parent, child, neighb;
+
+        while( -1!=p_loc && comp(container[loc].prio,container[p_loc].prio) ) {
+
+          // parent set for other loc_child
+          child=container[loc].child;
+          while( -1!=child ) {



More information about the Lemon-commits mailing list