sat-solver/BasicHeap.h
00001 /******************************************************************************************[Heap.h]
00002 MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
00005 associated documentation files (the "Software"), to deal in the Software without restriction,
00006 including without limitation the rights to use, copy, modify, merge, publish, distribute,
00007 sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00008 furnished to do so, subject to the following conditions:
00009 
00010 The above copyright notice and this permission notice shall be included in all copies or
00011 substantial portions of the Software.
00012 
00013 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
00014 NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00015 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00016 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
00017 OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00018 **************************************************************************************************/
00019 
00020 #ifndef BasicHeap_h
00021 #define BasicHeap_h
00022 
00023 #include "Vec.h"
00024 
00025 //=================================================================================================
00026 // A heap implementation with support for decrease/increase key.
00027 
00028 
00029 template<class Comp>
00030 class BasicHeap {
00031     Comp     lt;
00032     vec<int> heap;     // heap of ints
00033 
00034     // Index "traversal" functions
00035     static inline int left  (int i) { return i*2+1; }
00036     static inline int right (int i) { return (i+1)*2; }
00037     static inline int parent(int i) { return (i-1) >> 1; }
00038 
00039     inline void percolateUp(int i)
00040     {
00041         int x = heap[i];
00042         while (i != 0 && lt(x, heap[parent(i)])){
00043             heap[i]          = heap[parent(i)];
00044             i                = parent(i);
00045         }
00046         heap   [i] = x;
00047     }
00048 
00049 
00050     inline void percolateDown(int i)
00051     {
00052         int x = heap[i];
00053         while (left(i) < heap.size()){
00054             int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i);
00055             if (!lt(heap[child], x)) break;
00056             heap[i]          = heap[child];
00057             i                = child;
00058         }
00059         heap[i] = x;
00060     }
00061 
00062 
00063     bool heapProperty(int i) {
00064         return i >= heap.size()
00065             || ((i == 0 || !lt(heap[i], heap[parent(i)])) && heapProperty(left(i)) && heapProperty(right(i))); }
00066 
00067 
00068   public:
00069     BasicHeap(const C& c) : comp(c) { }
00070 
00071     int  size      ()                     const { return heap.size(); }
00072     bool empty     ()                     const { return heap.size() == 0; }
00073     int  operator[](int index)            const { return heap[index+1]; }
00074     void clear     (bool dealloc = false)       { heap.clear(dealloc); }
00075     void insert    (int n)                      { heap.push(n); percolateUp(heap.size()-1); }
00076 
00077 
00078     int  removeMin() {
00079         int r   = heap[0];
00080         heap[0] = heap.last();
00081         heap.pop();
00082         if (heap.size() > 1) percolateDown(0);
00083         return r; 
00084     }
00085 
00086 
00087     // DEBUG: consistency checking
00088     bool heapProperty() {
00089         return heapProperty(1); }
00090 
00091 
00092     // COMPAT: should be removed
00093     int  getmin    ()      { return removeMin(); }
00094 };
00095 
00096 
00097 //=================================================================================================
00098 #endif