LimitedHeap.h
Go to the documentation of this file.
1#ifndef __GfxTL_LIMITEDHEAP_HEADER__
2#define __GfxTL_LIMITEDHEAP_HEADER__
3#include <algorithm>
4#include <functional>
5#include <vector>
6
9
10namespace GfxTL
11{
12 template <class T,
13 class PredicateT = std::less<T>,
14 template <class> class ContainerT = FlatCopyVector>
15 class LimitedHeap : public ContainerT<T>
16 {
17 public:
18 typedef typename ContainerT<T>::value_type value_type;
19 typedef typename ContainerT<T>::size_type size_type;
20 typedef PredicateT PredicateType;
21 typedef ContainerT<T> BaseType;
22
23 LimitedHeap() : _limit(-1), _instances(0)
24 {
25 }
26
27 LimitedHeap(size_type limit) : _limit(limit), _instances(0)
28 {
29 BaseType::reserve(limit);
30 }
31
32 LimitedHeap(const PredicateType& pred) : m_pred(pred), _limit(-1), _instances(0)
33 {
34 BaseType::reserve(_limit);
35 }
36
37 LimitedHeap(size_type limit, const PredicateType& pred) :
38 m_pred(pred), _limit(limit), _instances(0)
39 {
40 BaseType::reserve(limit);
41 }
42
43 void
45 {
46 _limit = limit;
47 BaseType::reserve(limit + 1);
48 }
49
51 Limit() const
52 {
53 return _limit;
54 }
55
56 void
58 {
59 m_pred = pred;
60 }
61
62 const PredicateType&
63 Predicate() const
64 {
65 return m_pred;
66 }
67
68 void
70 {
71 BaseType::clear();
72 _instances = 0;
73 }
74
75 void
77 {
78 size_type iend = BaseType::size();
79 for (size_type i = BaseType::size() >> 1; i > 0; --i)
80 {
81 Heapify(i - 1, iend);
82 }
83 }
84
85 void
87 {
88 if (!BaseType::size())
89 {
90 return;
91 }
92 for (size_type i = BaseType::size() - 1; i > 0; --i)
93 {
94 T tmp = BaseType::at(i);
95 BaseType::at(i) = BaseType::at(0);
96 BaseType::at(0) = tmp;
97 Heapify(0, i);
98 }
99 }
100
101 void
103 {
104 if (BaseType::size() < _limit)
105 {
106 MakeHeap();
107 }
108 }
109
110 void
112 {
113 if (BaseType::size() < _limit)
114 {
115 BaseType::push_back(t);
116 if (BaseType::size() == _limit)
117 {
118 MakeHeap();
119 _instances = CountInstances(0);
120 }
121 }
122 else
123 {
124 if (m_pred(BaseType::front(), t)) // front < t
125 {
126 return; // t > front
127 }
128 if (m_pred(t, BaseType::front())) // t < front?
129 {
130 if (_instances > 1)
131 {
132 if (BaseType::size() + 1 - _instances >= _limit)
133 {
134 // remove instances
135 for (size_type i = 0; i < _instances; ++i)
136 {
137 std::swap(BaseType::front(), BaseType::back());
138 BaseType::pop_back();
139 Heapify(0, BaseType::size());
140 }
141 BaseType::push_back(t);
142 BubbleDown();
143 _instances = CountInstances(0);
144 return;
145 }
146 BaseType::push_back(t);
147 BubbleDown();
148 return;
149 }
150 BaseType::front() = t;
151 Heapify(0, BaseType::size());
152 _instances = CountInstances(0);
153 return;
154 }
155 // t == front;
156 BaseType::push_back(t);
157 BubbleDown();
158 ++_instances;
159 }
160 }
161
162 private:
163 void
164 Heapify(size_type i, size_type iend)
165 {
166 using namespace std;
168 while ((max = (i << 1) + 1) < iend)
169 {
170 if (max + 1 < iend && m_pred(BaseType::at(max), BaseType::at(max + 1)))
171 {
172 ++max;
173 }
174 if (!m_pred(BaseType::at(i), BaseType::at(max)))
175 {
176 break;
177 }
178 std::swap(BaseType::at(i), BaseType::at(max));
179 i = max;
180 }
181 }
182
183 void
184 BubbleDown()
185 {
186 using namespace std;
187 if (BaseType::size() == 1)
188 {
189 return;
190 }
191 size_type i = BaseType::size() - 1, j;
192 while (i && m_pred(BaseType::at(j = ((i + 1) >> 1) - 1), BaseType::at(i)))
193 {
194 std::swap(BaseType::at(i), BaseType::at(j));
195 i = j;
196 }
197 }
198
200 CountInstances(size_type i) const
201 {
202 size_type child = (i << 1) + 1;
203 if (child >= BaseType::size())
204 {
205 return 1;
206 }
207 size_type instances = 0;
208 if (!m_pred(BaseType::at(child), BaseType::at(i)))
209 {
210 instances = CountInstances(child);
211 }
212 ++child;
213 if (child >= BaseType::size())
214 {
215 return 1 + instances;
216 }
217 if (!m_pred(BaseType::at(child), BaseType::at(i)))
218 {
219 instances += CountInstances(child);
220 }
221 return 1 + instances;
222 }
223
224 private:
225 PredicateType m_pred;
226 size_type _limit;
227 size_type _instances;
228 };
229
230 template <class T, template <class> class ContainerT = FlatCopyVector>
231 class AssumeUniqueLimitedHeap : public ContainerT<T>
232 {
233 public:
234 typedef typename ContainerT<T>::value_type value_type;
235 typedef typename ContainerT<T>::size_type size_type;
236 typedef ContainerT<T> BaseType;
237
239 {
240 }
241
242 AssumeUniqueLimitedHeap(size_type limit) : _limit(limit)
243 {
244 BaseType::reserve(limit);
245 }
246
247 void
249 {
250 _limit = limit;
251 BaseType::reserve(limit + 1);
252 }
253
255 Limit() const
256 {
257 return _limit;
258 }
259
260 void
262 {
263 size_type iend = BaseType::size();
264 for (size_type i = BaseType::size() >> 1; i > 0; --i)
265 {
266 Heapify(i - 1, iend);
267 }
268 }
269
270 void
272 {
273 if (!BaseType::size())
274 {
275 return;
276 }
277 for (size_type i = BaseType::size() - 1; i > 0; --i)
278 {
279 T tmp = BaseType::at(i);
280 BaseType::at(i) = BaseType::at(0);
281 BaseType::at(0) = tmp;
282 Heapify(0, i);
283 }
284 }
285
286 void
288 {
289 if (BaseType::size() < _limit)
290 {
291 MakeHeap();
292 }
293 }
294
295 void
297 {
298 if (BaseType::size() < _limit)
299 {
300 BaseType::push_back(t);
301 if (BaseType::size() == _limit)
302 {
303 MakeHeap();
304 }
305 }
306 else
307 {
308 if (t >= BaseType::front())
309 {
310 return;
311 }
312 BaseType::front() = t;
313 Heapify(0, BaseType::size());
314 }
315 }
316
317 private:
318 void
319 Heapify(size_type i, size_type iend)
320 {
322 while ((max = (i << 1) + 1) < iend)
323 {
324 if (max + 1 < iend && BaseType::at(max) < BaseType::at(max + 1))
325 {
326 ++max;
327 }
328 if (BaseType::at(i) >= BaseType::at(max))
329 {
330 break;
331 }
332 std::swap(BaseType::at(i), BaseType::at(max));
333 i = max;
334 }
335 }
336
337 void
338 BubbleDown()
339 {
340 if (BaseType::size() == 1)
341 {
342 return;
343 }
344 size_type i = BaseType::size() - 1, j;
345 while (i && BaseType::at(i) > BaseType::at(j = ((i + 1) >> 1) - 1))
346 {
347 std::swap(BaseType::at(i), BaseType::at(j));
348 i = j;
349 }
350 }
351
352 private:
353 size_type _limit;
354 };
355}; // namespace GfxTL
356
357#endif
AssumeUniqueLimitedHeap(size_type limit)
void Limit(size_type limit)
ContainerT< T >::value_type value_type
ContainerT< T >::size_type size_type
void PushHeap(const value_type &t)
LimitedHeap(size_type limit, const PredicateType &pred)
Definition LimitedHeap.h:37
const PredicateType & Predicate() const
Definition LimitedHeap.h:63
size_type Limit() const
Definition LimitedHeap.h:51
void Limit(size_type limit)
Definition LimitedHeap.h:44
void Predicate(const PredicateType &pred)
Definition LimitedHeap.h:57
ContainerT< T >::value_type value_type
Definition LimitedHeap.h:18
ContainerT< T >::size_type size_type
Definition LimitedHeap.h:19
PredicateT PredicateType
Definition LimitedHeap.h:20
ContainerT< T > BaseType
Definition LimitedHeap.h:21
void PushHeap(const value_type &t)
LimitedHeap(size_type limit)
Definition LimitedHeap.h:27
LimitedHeap(const PredicateType &pred)
Definition LimitedHeap.h:32
T max(T t1, T t2)
Definition gdiam.h:51
Definition AABox.h:10
MatrixXX< C, R, T > max(const MatrixXX< C, R, T > &a, const MatrixXX< C, R, T > &b)
Definition MatrixXX.h:630