carl  24.04
Computer ARithmetic Library
Heap.h
Go to the documentation of this file.
1 /**
2  * @file Heap.h
3  * This file has been extracted from mathic. It was deployed without license at:
4  * http://www.broune.com/papers/issac2012.html
5  *
6  * As of now, it is available at @cite Mathic .
7  */
8 
9 #pragma once
10 
11 #include "CompactTree.h"
12 
13 #include <ostream>
14 #include <string>
15 #include <vector>
16 
17 namespace carl
18 {
19  /** A heap priority queue.
20 
21  Configuration serves the same role as for Geobucket. It must have these
22  fields that work as for Geobucket.
23 
24  * A type Entry
25  * A type CompareResult
26  * A const or static method: CompareResult compare(Entry, Entry)
27  * A const or static method: bool cmpLessThan(CompareResult)
28  * A static const bool supportDeduplication
29  * A static or const method: bool cmpEqual(CompareResult)
30  * A static or const method: Entry deduplicate(Entry a, Entry b)
31 
32 
33  It also has these additional fields:
34 
35  * A static const bool fastIndex
36  If this field is true, then a faster way of calculating indexes is used.
37  This requires sizeof(Entry) to be a power of two! This can be achieved
38  by adding padding to Entry, but this class does not do that for you.
39  */
40  template<class C>
41  class Heap
42  {
43  public:
44  class c_iterator;
45  using Configuration = C;
46  using Entry = typename Configuration::Entry;
47 
48  explicit Heap( const Configuration& configuration ):
49  _tree(),
50  _conf( configuration )
51  {}
53  {
54  return _conf;
55  }
56 
58  {
59  return _conf;
60  }
61 
62  std::string get_name() const;
63  void push( Entry entry );
64  void push( const Entry* begin, const Entry* end );
66 
67  Entry top() const
68  {
69  return _tree[Node()];
70  }
71 
72  bool empty() const
73  {
74  return _tree.empty();
75  }
76 
77  size_t size() const
78  {
79  return _tree.size();
80  }
81 
82  c_iterator begin() const
83  {
84  return c_iterator( _tree );
85  }
86 
87  c_iterator end() const
88  {
89  return c_iterator( _tree, _tree.lastLeaf().next() );
90  }
91 
92  std::vector<Entry> getCopy() const
93  {
94  _tree.getCopy();
95  }
96 
97  void print( std::ostream& out = std::cout ) const;
98 
99  void decreaseTop( Entry newEntry );
100  void decreasePos( Entry newEntry, c_iterator pos );
101 
103  {
104  Entry movedValue = _tree[_tree.lastLeaf()];
105  _tree.popBack();
106  if( !_tree.empty() )
107  moveValueUp( moveHoleDown( pos.getNode() ), movedValue );
108 
109  }
110 
111  size_t getMemoryUse() const;
112 
113  private:
115  using Node = typename Tree::Node;
116 
118  void moveValueDown( Node pos, Entry value );
119  void moveValueUp( Node pos, Entry value );
120 
121  bool isValid() const;
122 
125 
126  public:
128  {
129  public:
130  explicit c_iterator( const Tree& tree ):
131  mTree( tree ),
132  pos()
133  {}
134 
135 #ifdef __VS
136  c_iterator( const Tree& tree, Node startpos ):
137 #else
138  c_iterator(const Tree& tree, Heap::Node startpos) :
139 #endif
140  mTree( tree ),
141  pos( startpos )
142  {}
143 
144  const Entry get() const
145  {
146  return mTree[pos];
147  }
148 
149  void next()
150  {
151  pos = pos.next();
152  }
153 
154  friend bool operator ==( c_iterator lhs, c_iterator rhs )
155  {
156  if( &lhs.mTree != &rhs.mTree )
157  return false;
158  return lhs.pos == rhs.pos;
159  }
160 
161  friend bool operator !=( c_iterator lhs, c_iterator rhs )
162  {
163  return !(lhs == rhs);
164  }
165 
166  const Node& getNode() const
167  {
168  return pos;
169  }
170 
171  protected:
172 #ifdef __VS
173  const Tree& mTree;
174  Node pos;
175 #else
178 #endif
179 
180  };
181 
183  };
184 
185  template<class C>
186  size_t Heap<C>::getMemoryUse() const
187  {
188  return _tree.getMemoryUse();
189  }
190 
191  template<class C>
192  std::string Heap<C>::get_name() const
193  {
194  return std::string( "heap(" ) + (C::fastIndex ? "fi" : "si") + (C::supportDeduplicationWhileOrdering ? " dedup" : "") + ')';
195  }
196 
197  template<class C>
198  void Heap<C>::push( Entry entry )
199  {
200  assert( isValid() );
201  _tree.pushBack( entry );
202  moveValueUp( _tree.lastLeaf(), entry );
203  assert( isValid() );
204  }
205 
206  template<class C>
207  void Heap<C>::push( const Entry* begin, const Entry* end )
208  {
209  for( ; begin != end; ++begin )
210  push( *begin );
211  }
212 
213  template<class C>
214  void Heap<C>::decreaseTop( Entry newEntry )
215  {
216  moveValueUp( moveHoleDown( Node() ), newEntry );
217  assert( isValid() );
218  }
219 
220  template<class C>
222  {
223  Entry top = _tree[Node()];
224  Entry movedValue = _tree[_tree.lastLeaf()];
225  _tree.popBack();
226  if( !_tree.empty() )
227  moveValueUp( moveHoleDown( Node() ), movedValue );
228 
229  return top;
230  assert( isValid() );
231  }
232 
233  template<class C>
234  void Heap<C>::print( std::ostream& out ) const
235  {
236  out << get_name() << _tree.size() << ": {" << _tree << "}\n";
237  }
238 
239  template<class C>
241  {
242  const Node firstWithout2Children = _tree.lastLeaf().next().parent();
243  while( hole < firstWithout2Children )
244  {
245  // can assume hole has two children here
246  Node child = hole.left();
247  Node sibling = child.next();
248  if( _conf.cmpLessThan( _conf.compare( _tree[child], _tree[sibling] )))
249  child = sibling;
250  _tree[hole] = _tree[child];
251  hole = child;
252  }
253  // if we are at a node that has a single left child
254  if( hole == firstWithout2Children && _tree.lastLeaf().isLeft() )
255  {
256  Node child = hole.left();
257  _tree[hole] = _tree[child];
258  return child;
259  }
260  return hole;
261  }
262 
263  /*template<class C>
264  void Heap<C>::moveValueDown(Node pos, Entry value) {
265  const Node firstWithout2Children = _tree.lastLeaf().next().parent();
266  while (pos < firstWithout2Children) {
267  // can assume hole has two children here
268  Node child = pos.left();
269  Node sibling = child.next();
270  if (_conf.cmpLessThan(_conf.compare(_tree[child], _tree[sibling])))
271  child = sibling;
272  if(_conf.cmpLessThan(_conf.compare(value, _tree[child]))) {
273  _tree[pos] = _tree[child];
274  pos = child;
275  }
276  }
277  // if we are at a node that has a single left child
278  if (pos == firstWithout2Children && _tree.lastLeaf().isLeft()) {
279  Node child = pos.left();
280  _tree[pos] = _tree[child];
281  return child;
282  }
283  return hole;
284  }*/
285 
286  template<class C>
287  void Heap<C>::moveValueUp( Node pos, Entry value )
288  {
289  //const Node origPos = pos;
290  while( !pos.isRoot() )
291  {
292  const Node up = pos.parent();
293  typename C::CompareResult cmp = _conf.compare( _tree[up], value );
294  if( _conf.cmpLessThan( cmp ))
295  {
296  _tree[pos] = _tree[up];
297  pos = up;
298  }
299  else if( C::supportDeduplicationWhileOrdering && _conf.cmpEqual( cmp ))
300  {
301  assert( false );
302  // bool elimToZero = _conf.deduplicate(_tree[up], value);
303  //Since value now is smaller, we have to move it down in the tree..
304  // pos = moveHoleDown(pos);
305  //if value is now empty
306  // if(value->empty()) {
307  // std::swap(_tree[pos], _tree[_tree.lastLeaf()]);
308  //remove empty from the tree.
309  // _tree.popBack();
310  // return;
311  // }
312  //otherwise we just move it up again.
313 
314  // if(elimToZero) {
315  //we do not do anything with this.
316  // }
317 
318  // continue;
319  }
320  else
321  {
322  break;
323  }
324  }
325  _tree[pos] = value;
326  assert( isValid() );
327  }
328 
329  template<class C>
330  bool Heap<C>::isValid() const
331  {
332  assert( _tree.isValid() );
333  //print();
334  for( Node i = Node().next(); i <= _tree.lastLeaf(); ++i )
335  {
336  // if(_conf.cmpLessThan(_conf.compare(_tree[i.parent()], _tree[i]))) {
337  // std::cout << i.parent()._index << ": ";
338  // _tree[i.parent()]->print();
339  // std::cout << std::endl;
340  //
341  // std::cout << i._index << ": ";
342  // _tree[i]->print();
343  // std::cout << std::endl;
344  // print();
345  // }
346  assert( !_conf.cmpLessThan( _conf.compare( _tree[i.parent()], _tree[i] )));
347  }
348  return true;
349  }
350 }
This file has been extracted from mathic.
carl is the main namespace for the library.
CompareResult
Definition: CompareResult.h:12
This class represents a tree.
Definition: carlTree.h:559
std::vector< Entry > getCopy() const
Definition: CompactTree.h:174
bool empty() const
Definition: CompactTree.h:56
std::size_t size() const
Definition: CompactTree.h:61
Node lastLeaf() const
Definition: CompactTree.h:71
A heap priority queue.
Definition: Heap.h:42
C Configuration
Definition: Heap.h:45
Entry top() const
Definition: Heap.h:67
void popPosition(c_iterator pos)
Definition: Heap.h:102
size_t getMemoryUse() const
Definition: Heap.h:186
void print(std::ostream &out=std::cout) const
Definition: Heap.h:234
void push(const Entry *begin, const Entry *end)
Definition: Heap.h:207
c_iterator begin() const
Definition: Heap.h:82
bool isValid() const
Definition: Heap.h:330
void push(Entry entry)
Definition: Heap.h:198
Tree _tree
Definition: Heap.h:123
size_t size() const
Definition: Heap.h:77
void moveValueUp(Node pos, Entry value)
Definition: Heap.h:287
Entry pop()
Definition: Heap.h:221
std::vector< Entry > getCopy() const
Definition: Heap.h:92
std::string get_name() const
Definition: Heap.h:192
Node moveHoleDown(Node hole)
Definition: Heap.h:240
void moveValueDown(Node pos, Entry value)
Heap(const Configuration &configuration)
Definition: Heap.h:48
typename Tree::Node Node
Definition: Heap.h:115
typename Configuration::Entry Entry
Definition: Heap.h:46
Configuration & getConfiguration()
Definition: Heap.h:52
Configuration _conf
Definition: Heap.h:124
bool empty() const
Definition: Heap.h:72
void decreaseTop(Entry newEntry)
Definition: Heap.h:214
const Configuration & getConfiguration() const
Definition: Heap.h:57
c_iterator end() const
Definition: Heap.h:87
void decreasePos(Entry newEntry, c_iterator pos)
friend bool operator!=(c_iterator lhs, c_iterator rhs)
Definition: Heap.h:161
const Node & getNode() const
Definition: Heap.h:166
friend bool operator==(c_iterator lhs, c_iterator rhs)
Definition: Heap.h:154
Heap::Node pos
Definition: Heap.h:177
c_iterator(const Tree &tree)
Definition: Heap.h:130
const Entry get() const
Definition: Heap.h:144
const Heap::Tree & mTree
Definition: Heap.h:176