[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