ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
heap.hpp
Go to the documentation of this file.
1#ifndef _heap_hpp_INCLUDED
2#define _heap_hpp_INCLUDED
3
4#include "global.h"
5
6#include "util.hpp" // Alphabetically after 'heap.hpp'.
7
8#include <cassert>
9
11
12namespace CaDiCaL {
13
14using namespace std;
15
16// This is a priority queue with updates for unsigned integers implemented
17// as binary heap. We need to map integer elements added (through
18// 'push_back') to positions on the binary heap in 'array'. This map is
19// stored in the 'pos' array. This approach is really wasteful (at least in
20// terms of memory) if only few and a sparse set of integers is added. So
21// it should not be used in this situation. A generic priority queue would
22// implement the mapping externally provided by another template parameter.
23// Since we use 'UINT_MAX' as 'not contained' flag, we can only have
24// 'UINT_MAX - 1' elements in the heap.
25
26const unsigned invalid_heap_position = UINT_MAX;
27
28template <class C> class heap {
29
30 vector<unsigned> array; // actual binary heap
31 vector<unsigned> pos; // positions of elements in array
32 C less; // less-than for elements
33
34 // Map an element to its position entry in the 'pos' map.
35 //
36 unsigned &index (unsigned e) {
37 if (e >= pos.size ())
38 pos.resize (1 + (size_t) e, invalid_heap_position);
39 unsigned &res = pos[e];
40 CADICAL_assert (res == invalid_heap_position || (size_t) res < array.size ());
41 return res;
42 }
43
44 bool has_parent (unsigned e) { return index (e) > 0; }
45 bool has_left (unsigned e) {
46 return (size_t) 2 * index (e) + 1 < size ();
47 }
48 bool has_right (unsigned e) {
49 return (size_t) 2 * index (e) + 2 < size ();
50 }
51
52 unsigned parent (unsigned e) {
53 CADICAL_assert (has_parent (e));
54 return array[(index (e) - 1) / 2];
55 }
56
57 unsigned left (unsigned e) {
58 CADICAL_assert (has_left (e));
59 return array[2 * index (e) + 1];
60 }
61
62 unsigned right (unsigned e) {
63 CADICAL_assert (has_right (e));
64 return array[2 * index (e) + 2];
65 }
66
67 // Exchange elements 'a' and 'b' in 'array' and fix their positions.
68 //
69 void exchange (unsigned a, unsigned b) {
70 unsigned &i = index (a), &j = index (b);
71 swap (array[i], array[j]);
72 swap (i, j);
73 }
74
75 // Bubble up an element as far as necessary.
76 //
77 void up (unsigned e) {
78 unsigned p;
79 while (has_parent (e) && less ((p = parent (e)), e))
80 exchange (p, e);
81 }
82
83 // Bubble down an element as far as necessary.
84 //
85 void down (unsigned e) {
86 while (has_left (e)) {
87 unsigned c = left (e);
88 if (has_right (e)) {
89 unsigned r = right (e);
90 if (less (c, r))
91 c = r;
92 }
93 if (!less (e, c))
94 break;
95 exchange (e, c);
96 }
97 }
98
99 // Very expensive checker for the main 'heap' invariant. Can be enabled
100 // to find violations of antisymmetry in the client implementation of
101 // 'less' and as well of course bugs in this heap implementation. It
102 // should be enabled during testing applications of the heap.
103 //
104 void check () {
105#if 0 // EXPENSIVE HEAP CHECKING IF ENABLED
106#warning "expensive checking in heap enabled"
107 CADICAL_assert (array.size () <= invalid_heap_position);
108 for (size_t i = 0; i < array.size (); i++) {
109 size_t l = 2*i + 1, r = 2*i + 2;
110 if (l < array.size ()) CADICAL_assert (!less (array[i], array[l]));
111 if (r < array.size ()) CADICAL_assert (!less (array[i], array[r]));
112 CADICAL_assert (array[i] >= 0);
113 {
114 CADICAL_assert ((size_t) array[i] < pos.size ());
115 CADICAL_assert (i == (size_t) pos[array[i]]);
116 }
117 }
118 for (size_t i = 0; i < pos.size (); i++) {
119 if (pos[i] == invalid_heap_position) continue;
120 CADICAL_assert (pos[i] < array.size ());
121 CADICAL_assert (array[pos[i]] == (unsigned) i);
122 }
123#endif
124 }
125
126public:
127 heap (const C &c) : less (c) {}
128
129 // Number of elements in the heap.
130 //
131 size_t size () const { return array.size (); }
132
133 // Check if no more elements are in the heap.
134 //
135 bool empty () const { return array.empty (); }
136
137 // Check whether 'e' is already in the heap.
138 //
139 bool contains (unsigned e) const {
140 if ((size_t) e >= pos.size ())
141 return false;
142 return pos[e] != invalid_heap_position;
143 }
144
145 // Add a new (not contained) element 'e' to the heap.
146 //
147 void push_back (unsigned e) {
149 size_t i = array.size ();
151 array.push_back (e);
152 index (e) = (unsigned) i;
153 up (e);
154 down (e);
155 check ();
156 }
157
158 // Returns the maximum element in the heap.
159 //
160 unsigned front () const {
161 CADICAL_assert (!empty ());
162 return array[0];
163 }
164
165 // Removes the maximum element in the heap.
166 //
167 unsigned pop_front () {
168 CADICAL_assert (!empty ());
169 unsigned res = array[0], last = array.back ();
170 if (size () > 1)
171 exchange (res, last);
172 index (res) = invalid_heap_position;
173 array.pop_back ();
174 if (size () > 1)
175 down (last);
176 check ();
177 return res;
178 }
179
180 // Notify the heap, that evaluation of 'less' has changed for 'e'.
181 //
182 void update (unsigned e) {
184 up (e);
185 down (e);
186 check ();
187 }
188
189 void clear () {
190 array.clear ();
191 pos.clear ();
192 }
193
194 void erase () {
195 erase_vector (array);
196 erase_vector (pos);
197 }
198
199 void shrink () {
200 shrink_vector (array);
201 shrink_vector (pos);
202 }
203
204 // Standard iterators 'inherited' from 'vector'.
205 //
208 iterator begin () { return array.begin (); }
209 iterator end () { return array.end (); }
210 const_iterator begin () const { return array.begin (); }
211 const_iterator end () const { return array.end (); }
212};
213
214} // namespace CaDiCaL
215
217
218#endif
#define ABC_NAMESPACE_CXX_HEADER_START
#define ABC_NAMESPACE_CXX_HEADER_END
#define CADICAL_assert(ignore)
Definition global.h:14
void erase()
Definition heap.hpp:194
bool empty() const
Definition heap.hpp:135
void shrink()
Definition heap.hpp:199
bool contains(unsigned e) const
Definition heap.hpp:139
const_iterator begin() const
Definition heap.hpp:210
iterator end()
Definition heap.hpp:209
size_t size() const
Definition heap.hpp:131
const_iterator end() const
Definition heap.hpp:211
void clear()
Definition heap.hpp:189
iterator begin()
Definition heap.hpp:208
void push_back(unsigned e)
Definition heap.hpp:147
vector< unsigned >::iterator iterator
Definition heap.hpp:206
unsigned pop_front()
Definition heap.hpp:167
vector< unsigned >::const_iterator const_iterator
Definition heap.hpp:207
unsigned front() const
Definition heap.hpp:160
void update(unsigned e)
Definition heap.hpp:182
heap(const C &c)
Definition heap.hpp:127
Cube * p
Definition exorList.c:222
const unsigned invalid_heap_position
Definition heap.hpp:26
void shrink_vector(std::vector< T > &v)
Definition util.hpp:101
void erase_vector(std::vector< T > &v)
Definition util.hpp:90