heap.h
Go to the documentation of this file.
00001 /***********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
00005  * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
00006  *
00007  * THE BSD LICENSE
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  *
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00020  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00021  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00022  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00023  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00024  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00025  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00026  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00028  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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         /* If heap is full, then return without adding this element. */
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;  /* Return old last node. */
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); // 1-based indexing
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         /* If heap is full, then return without adding this element. */
00233         if (size_ == capacity_) {
00234             return;
00235         }
00236 
00237         // insert into the root
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) { // odd number of elements
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) { // duplicate element in last position if size is odd
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) { // duplicate element in last position if size is odd
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) { // odd number of elements
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; // root node
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; // pick the child with min
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) { // odd number of elements
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; // root node
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; // pick the child with max
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_


rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jun 6 2019 21:59:20