Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef RTABMAP_FLANN_HEAP_H_
00032 #define RTABMAP_FLANN_HEAP_H_
00033
00034 #include <algorithm>
00035 #include <vector>
00036 #include <rtabmap/utilite/ULogger.h>
00037
00038 namespace rtflann
00039 {
00040
00048 template <typename T>
00049 class Heap
00050 {
00051
00056 std::vector<T> heap;
00057 int length;
00058
00062 int count;
00063
00064
00065
00066 public:
00074 Heap(int size)
00075 {
00076 length = size;
00077 heap.reserve(length);
00078 count = 0;
00079 }
00080
00085 int size()
00086 {
00087 return count;
00088 }
00089
00094 int capacity()
00095 {
00096 return length;
00097 }
00098
00104 bool empty()
00105 {
00106 return size()==0;
00107 }
00108
00112 void clear()
00113 {
00114 heap.clear();
00115 count = 0;
00116 }
00117
00118 struct CompareT : public std::binary_function<T,T,bool>
00119 {
00120 bool operator()(const T& t_1, const T& t_2) const
00121 {
00122 return t_2 < t_1;
00123 }
00124 };
00125
00135 void insert(const T& value)
00136 {
00137
00138 if (count == length) {
00139 return;
00140 }
00141
00142 UASSERT(heap.size() < heap.capacity());
00143 heap.push_back(value);
00144 static CompareT compareT;
00145 std::push_heap(heap.begin(), heap.end(), compareT);
00146 ++count;
00147 }
00148
00149
00150
00158 bool popMin(T& value)
00159 {
00160 if (count == 0) {
00161 return false;
00162 }
00163
00164 value = heap[0];
00165 static CompareT compareT;
00166 std::pop_heap(heap.begin(), heap.end(), compareT);
00167 heap.pop_back();
00168 --count;
00169
00170 return true;
00171 }
00172 };
00173
00174
00175 template <typename T>
00176 class IntervalHeap
00177 {
00178 struct Interval
00179 {
00180 T left;
00181 T right;
00182 };
00183
00188 std::vector<Interval> heap;
00189 size_t capacity_;
00190 size_t size_;
00191
00192 public:
00200 IntervalHeap(int capacity) : capacity_(capacity), size_(0)
00201 {
00202 heap.resize(capacity/2 + capacity%2 + 1);
00203 }
00204
00208 size_t size()
00209 {
00210 return size_;
00211 }
00212
00217 bool empty()
00218 {
00219 return size_==0;
00220 }
00221
00225 void clear()
00226 {
00227 size_ = 0;
00228 }
00229
00230 void insert(const T& value)
00231 {
00232
00233 if (size_ == capacity_) {
00234 return;
00235 }
00236
00237
00238 if (size_<2) {
00239 if (size_==0) {
00240 heap[1].left = value;
00241 heap[1].right = value;
00242 }
00243 else {
00244 if (value<heap[1].left) {
00245 heap[1].left = value;
00246 }
00247 else {
00248 heap[1].right = value;
00249 }
00250 }
00251 ++size_;
00252 return;
00253 }
00254
00255 size_t last_pos = size_/2 + size_%2;
00256 bool min_heap;
00257
00258 if (size_%2) {
00259 min_heap = (value<heap[last_pos].left)? true : false;
00260 }
00261 else {
00262 ++last_pos;
00263 min_heap = (value<heap[last_pos/2].left)? true : false;
00264 }
00265
00266 if (min_heap) {
00267 size_t pos = last_pos;
00268 size_t par = pos/2;
00269 while (pos>1 && value < heap[par].left) {
00270 heap[pos].left = heap[par].left;
00271 pos = par;
00272 par = pos/2;
00273 }
00274 heap[pos].left = value;
00275 ++size_;
00276
00277 if (size_%2) {
00278 heap[last_pos].right = heap[last_pos].left;
00279 }
00280 }
00281 else {
00282 size_t pos = last_pos;
00283 size_t par = pos/2;
00284 while (pos>1 && heap[par].right < value) {
00285 heap[pos].right = heap[par].right;
00286 pos = par;
00287 par = pos/2;
00288 }
00289 heap[pos].right = value;
00290 ++size_;
00291
00292 if (size_%2) {
00293 heap[last_pos].left = heap[last_pos].right;
00294 }
00295 }
00296 }
00297
00298
00304 bool popMin(T& value)
00305 {
00306 if (size_ == 0) {
00307 return false;
00308 }
00309
00310 value = heap[1].left;
00311 size_t last_pos = size_/2 + size_%2;
00312 T elem = heap[last_pos].left;
00313
00314 if (size_ % 2) {
00315 --last_pos;
00316 }
00317 else {
00318 heap[last_pos].left = heap[last_pos].right;
00319 }
00320 --size_;
00321 if (size_<2) return true;
00322
00323 size_t crt=1;
00324 size_t child = crt*2;
00325
00326 while (child <= last_pos) {
00327 if (child < last_pos && heap[child+1].left < heap[child].left) ++child;
00328
00329 if (!(heap[child].left<elem)) break;
00330
00331 heap[crt].left = heap[child].left;
00332 if (heap[child].right<elem) {
00333 std::swap(elem, heap[child].right);
00334 }
00335
00336 crt = child;
00337 child *= 2;
00338 }
00339 heap[crt].left = elem;
00340 return true;
00341 }
00342
00343
00349 bool popMax(T& value)
00350 {
00351 if (size_ == 0) {
00352 return false;
00353 }
00354
00355 value = heap[1].right;
00356 size_t last_pos = size_/2 + size_%2;
00357 T elem = heap[last_pos].right;
00358
00359 if (size_%2) {
00360 --last_pos;
00361 }
00362 else {
00363 heap[last_pos].right = heap[last_pos].left;
00364 }
00365 --size_;
00366 if (size_<2) return true;
00367
00368 size_t crt=1;
00369 size_t child = crt*2;
00370
00371 while (child <= last_pos) {
00372 if (child < last_pos && heap[child].right < heap[child+1].right) ++child;
00373
00374 if (!(elem < heap[child].right)) break;
00375
00376 heap[crt].right = heap[child].right;
00377 if (elem<heap[child].left) {
00378 std::swap(elem, heap[child].left);
00379 }
00380
00381 crt = child;
00382 child *= 2;
00383 }
00384 heap[crt].right = elem;
00385 return true;
00386 }
00387
00388
00389 bool getMin(T& value)
00390 {
00391 if (size_==0) {
00392 return false;
00393 }
00394 value = heap[1].left;
00395 return true;
00396 }
00397
00398
00399 bool getMax(T& value)
00400 {
00401 if (size_==0) {
00402 return false;
00403 }
00404 value = heap[1].right;
00405 return true;
00406 }
00407 };
00408
00409
00410 template <typename T>
00411 class BoundedHeap
00412 {
00413 IntervalHeap<T> interval_heap_;
00414 size_t capacity_;
00415 public:
00416 BoundedHeap(size_t capacity) : interval_heap_(capacity), capacity_(capacity)
00417 {
00418
00419 }
00420
00424 int size()
00425 {
00426 return interval_heap_.size();
00427 }
00428
00433 bool empty()
00434 {
00435 return interval_heap_.empty();
00436 }
00437
00441 void clear()
00442 {
00443 interval_heap_.clear();
00444 }
00445
00446 void insert(const T& value)
00447 {
00448 if (interval_heap_.size()==capacity_) {
00449 T max;
00450 interval_heap_.getMax(max);
00451 if (max<value) return;
00452 interval_heap_.popMax(max);
00453 }
00454 interval_heap_.insert(value);
00455 }
00456
00457 bool popMin(T& value)
00458 {
00459 return interval_heap_.popMin(value);
00460 }
00461 };
00462
00463
00464
00465 }
00466
00467 #endif //FLANN_HEAP_H_