bin_heap.h

Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 * src/lemon/bin_heap.h - Part of LEMON, a generic C++ optimization library 00003 * 00004 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 00005 * (Egervary Combinatorial Optimization Research Group, EGRES). 00006 * 00007 * Permission to use, modify and distribute this software is granted 00008 * provided that this copyright notice appears in all copies. For 00009 * precise terms see the accompanying LICENSE file. 00010 * 00011 * This software is provided "AS IS" with no warranty of any kind, 00012 * express or implied, and with no claim as to its suitability for any 00013 * purpose. 00014 * 00015 */ 00016 00017 #ifndef LEMON_BIN_HEAP_H 00018 #define LEMON_BIN_HEAP_H 00019 00024 00025 #include <vector> 00026 #include <utility> 00027 #include <functional> 00028 00029 namespace lemon { 00030 00033 00035 template <typename Item, typename Prio, typename ItemIntMap, 00036 typename Compare = std::less<Prio> > 00037 class BinHeap { 00038 00039 public: 00040 typedef Item ItemType; 00041 // FIXME: stl-ben nem ezt hivjak value_type -nak, hanem a kovetkezot... 00042 typedef Prio PrioType; 00043 typedef std::pair<ItemType,PrioType> PairType; 00044 typedef ItemIntMap ItemIntMapType; 00045 typedef Compare PrioCompare; 00046 00055 00056 00057 enum state_enum { 00058 IN_HEAP = 0, 00059 PRE_HEAP = -1, 00060 POST_HEAP = -2 00061 }; 00062 00063 private: 00064 std::vector<PairType> data; 00065 Compare comp; 00066 // FIXME: jo ez igy??? 00067 ItemIntMap &iim; 00068 00069 public: 00070 BinHeap(ItemIntMap &_iim) : iim(_iim) {} 00071 BinHeap(ItemIntMap &_iim, const Compare &_comp) : comp(_comp), iim(_iim) {} 00072 00073 00074 int size() const { return data.size(); } 00075 bool empty() const { return data.empty(); } 00076 00077 private: 00078 static int parent(int i) { return (i-1)/2; } 00079 static int second_child(int i) { return 2*i+2; } 00080 bool less(const PairType &p1, const PairType &p2) const { 00081 return comp(p1.second, p2.second); 00082 } 00083 00084 int bubble_up(int hole, PairType p); 00085 int bubble_down(int hole, PairType p, int length); 00086 00087 void move(const PairType &p, int i) { 00088 data[i] = p; 00089 iim.set(p.first, i); 00090 } 00091 00092 void rmidx(int h) { 00093 int n = data.size()-1; 00094 if( h>=0 && h<=n ) { 00095 iim.set(data[h].first, POST_HEAP); 00096 if ( h<n ) { 00097 bubble_down(h, data[n], n); 00098 } 00099 data.pop_back(); 00100 } 00101 } 00102 00103 public: 00104 void push(const PairType &p) { 00105 int n = data.size(); 00106 data.resize(n+1); 00107 bubble_up(n, p); 00108 } 00109 void push(const Item &i, const Prio &p) { push(PairType(i,p)); } 00110 00111 Item top() const { 00112 return data[0].first; 00113 } 00115 Prio prio() const { 00116 return data[0].second; 00117 } 00118 00119 void pop() { 00120 rmidx(0); 00121 } 00122 00123 void erase(const Item &i) { 00124 rmidx(iim[i]); 00125 } 00126 00127 Prio operator[](const Item &i) const { 00128 int idx = iim[i]; 00129 return data[idx].second; 00130 } 00131 00132 void set(const Item &i, const Prio &p) { 00133 int idx = iim[i]; 00134 if( idx < 0 ) { 00135 push(i,p); 00136 } 00137 else if( comp(p, data[idx].second) ) { 00138 bubble_up(idx, PairType(i,p)); 00139 } 00140 else { 00141 bubble_down(idx, PairType(i,p), data.size()); 00142 } 00143 } 00144 00145 void decrease(const Item &i, const Prio &p) { 00146 int idx = iim[i]; 00147 bubble_up(idx, PairType(i,p)); 00148 } 00149 void increase(const Item &i, const Prio &p) { 00150 int idx = iim[i]; 00151 bubble_down(idx, PairType(i,p), data.size()); 00152 } 00153 00154 state_enum state(const Item &i) const { 00155 int s = iim[i]; 00156 if( s>=0 ) 00157 s=0; 00158 return state_enum(s); 00159 } 00160 00161 }; // class BinHeap 00162 00163 00164 template <typename K, typename V, typename M, typename C> 00165 int BinHeap<K,V,M,C>::bubble_up(int hole, PairType p) { 00166 int par = parent(hole); 00167 while( hole>0 && less(p,data[par]) ) { 00168 move(data[par],hole); 00169 hole = par; 00170 par = parent(hole); 00171 } 00172 move(p, hole); 00173 return hole; 00174 } 00175 00176 template <typename K, typename V, typename M, typename C> 00177 int BinHeap<K,V,M,C>::bubble_down(int hole, PairType p, int length) { 00178 int child = second_child(hole); 00179 while(child < length) { 00180 if( less(data[child-1], data[child]) ) { 00181 --child; 00182 } 00183 if( !less(data[child], p) ) 00184 goto ok; 00185 move(data[child], hole); 00186 hole = child; 00187 child = second_child(hole); 00188 } 00189 child--; 00190 if( child<length && less(data[child], p) ) { 00191 move(data[child], hole); 00192 hole=child; 00193 } 00194 ok: 00195 move(p, hole); 00196 return hole; 00197 } 00198 00200 00201 } // namespace lemon 00202 00203 #endif // LEMON_BIN_HEAP_H

Generated on Thu Sep 30 12:18:33 2004 for LEMON by doxygen 1.3.8