COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/bin_heap.h @ 1164:80bb73097736

Last change on this file since 1164:80bb73097736 was 1164:80bb73097736, checked in by Alpar Juttner, 15 years ago

A year has passed again.

File size: 5.1 KB
Line 
1/* -*- C++ -*-
2 * src/lemon/bin_heap.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
6 *
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
10 *
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
13 * purpose.
14 *
15 */
16
17#ifndef LEMON_BIN_HEAP_H
18#define LEMON_BIN_HEAP_H
19
20///\ingroup auxdat
21///\file
22///\brief Binary Heap implementation.
23///\todo It should be documented.
24
25#include <vector>
26#include <utility>
27#include <functional>
28
29namespace lemon {
30
31  /// \addtogroup auxdat
32  /// @{
33
34   /// A Binary Heap implementation.
35 
36  ///\todo Please document...
37  ///
38  ///\sa FibHeap
39  ///\sa Dijkstra
40  template <typename Item, typename Prio, typename ItemIntMap,
41            typename Compare = std::less<Prio> >
42  class BinHeap {
43
44  public:
45    typedef Item                             ItemType;
46    // FIXME: stl-ben nem ezt hivjak value_type -nak, hanem a kovetkezot...
47    typedef Prio                             PrioType;
48    typedef std::pair<ItemType,PrioType>     PairType;
49    typedef ItemIntMap                       ItemIntMapType;
50    typedef Compare                          PrioCompare;
51
52    /**
53     * Each Item element have a state associated to it. It may be "in heap",
54     * "pre heap" or "post heap". The later two are indifferent from the
55     * heap's point of view, but may be useful to the user.
56     *
57     * The ItemIntMap _should_ be initialized in such way, that it maps
58     * PRE_HEAP (-1) to any element to be put in the heap...
59     */
60    ///\todo it is used nowhere
61    ///
62    enum state_enum {
63      IN_HEAP = 0,
64      PRE_HEAP = -1,
65      POST_HEAP = -2
66    };
67
68  private:
69    std::vector<PairType> data;
70    Compare comp;
71    // FIXME: jo ez igy???
72    ItemIntMap &iim;
73
74  public:
75    ///\e
76    BinHeap(ItemIntMap &_iim) : iim(_iim) {}
77    ///\e
78    BinHeap(ItemIntMap &_iim, const Compare &_comp) : comp(_comp), iim(_iim) {}
79
80
81    ///\e
82    int size() const { return data.size(); }
83    ///\e
84    bool empty() const { return data.empty(); }
85
86  private:
87    static int parent(int i) { return (i-1)/2; }
88    static int second_child(int i) { return 2*i+2; }
89    bool less(const PairType &p1, const PairType &p2) const {
90      return comp(p1.second, p2.second);
91    }
92
93    int bubble_up(int hole, PairType p);
94    int bubble_down(int hole, PairType p, int length);
95
96    void move(const PairType &p, int i) {
97      data[i] = p;
98      iim.set(p.first, i);
99    }
100
101    void rmidx(int h) {
102      int n = data.size()-1;
103      if( h>=0 && h<=n ) {
104        iim.set(data[h].first, POST_HEAP);
105        if ( h<n ) {
106          bubble_down(h, data[n], n);
107        }
108        data.pop_back();
109      }
110    }
111
112  public:
113    ///\e
114    void push(const PairType &p) {
115      int n = data.size();
116      data.resize(n+1);
117      bubble_up(n, p);
118    }
119    ///\e
120    void push(const Item &i, const Prio &p) { push(PairType(i,p)); }
121
122    ///\e
123    Item top() const {
124      return data[0].first;
125    }
126    /// Returns the prio of the top element of the heap.
127    Prio prio() const {
128      return data[0].second;
129    }
130
131    ///\e
132    void pop() {
133      rmidx(0);
134    }
135
136    ///\e
137    void erase(const Item &i) {
138      rmidx(iim[i]);
139    }
140
141    ///\e
142    Prio operator[](const Item &i) const {
143      int idx = iim[i];
144      return data[idx].second;
145    }
146
147    ///\e
148    void set(const Item &i, const Prio &p) {
149      int idx = iim[i];
150      if( idx < 0 ) {
151        push(i,p);
152      }
153      else if( comp(p, data[idx].second) ) {
154        bubble_up(idx, PairType(i,p));
155      }
156      else {
157        bubble_down(idx, PairType(i,p), data.size());
158      }
159    }
160
161    ///\e
162    void decrease(const Item &i, const Prio &p) {
163      int idx = iim[i];
164      bubble_up(idx, PairType(i,p));
165    }
166    ///\e
167    void increase(const Item &i, const Prio &p) {
168      int idx = iim[i];
169      bubble_down(idx, PairType(i,p), data.size());
170    }
171
172    ///\e
173    state_enum state(const Item &i) const {
174      int s = iim[i];
175      if( s>=0 )
176        s=0;
177      return state_enum(s);
178    }
179
180  }; // class BinHeap
181
182 
183  template <typename K, typename V, typename M, typename C>
184  int BinHeap<K,V,M,C>::bubble_up(int hole, PairType p) {
185    int par = parent(hole);
186    while( hole>0 && less(p,data[par]) ) {
187      move(data[par],hole);
188      hole = par;
189      par = parent(hole);
190    }
191    move(p, hole);
192    return hole;
193  }
194
195  template <typename K, typename V, typename M, typename C>
196  int BinHeap<K,V,M,C>::bubble_down(int hole, PairType p, int length) {
197    int child = second_child(hole);
198    while(child < length) {
199      if( less(data[child-1], data[child]) ) {
200        --child;
201      }
202      if( !less(data[child], p) )
203        goto ok;
204      move(data[child], hole);
205      hole = child;
206      child = second_child(hole);
207    }
208    child--;
209    if( child<length && less(data[child], p) ) {
210      move(data[child], hole);
211      hole=child;
212    }
213  ok:
214    move(p, hole);
215    return hole;
216  }
217
218  ///@}
219
220} // namespace lemon
221
222#endif // LEMON_BIN_HEAP_H
Note: See TracBrowser for help on using the repository browser.