Branch data Line data Source code
1 : : /******************************************************************************************[Heap.h] 2 : : Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson 3 : : Copyright (c) 2007-2010, Niklas Sorensson 4 : : 5 : : Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 6 : : associated documentation files (the "Software"), to deal in the Software without restriction, 7 : : including without limitation the rights to use, copy, modify, merge, publish, distribute, 8 : : sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 9 : : furnished to do so, subject to the following conditions: 10 : : 11 : : The above copyright notice and this permission notice shall be included in all copies or 12 : : substantial portions of the Software. 13 : : 14 : : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 15 : : NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 16 : : NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 : : DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 18 : : OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 : : **************************************************************************************************/ 20 : : 21 : : #ifndef Minisat_Heap_h 22 : : #define Minisat_Heap_h 23 : : 24 : : #include "base/check.h" 25 : : #include "prop/minisat/mtl/Vec.h" 26 : : 27 : : namespace cvc5::internal { 28 : : namespace Minisat { 29 : : 30 : : //================================================================================================= 31 : : // A heap implementation with support for decrease/increase key. 32 : : 33 : : 34 : : template<class Comp> 35 : : class Heap { 36 : : Comp lt; // The heap is a minimum-heap with respect to this comparator 37 : : vec<int> heap; // Heap of integers 38 : : vec<int> indices; // Each integers position (index) in the Heap 39 : : 40 : : // Index "traversal" functions 41 : 164991190 : static inline int left (int i) { return i*2+1; } 42 : 149983690 : static inline int right (int i) { return (i+1)*2; } 43 : 112738234 : static inline int parent(int i) { return (i-1) >> 1; } 44 : : 45 : : 46 : 47322946 : void percolateUp(int i) 47 : : { 48 : 47322946 : int x = heap[i]; 49 : 47322946 : int p = parent(i); 50 : : 51 [ + + ][ + + ]: 112738234 : while (i != 0 && lt(x, heap[p])){ [ + + ] 52 : 65414888 : heap[i] = heap[p]; 53 : 65414888 : indices[heap[p]] = i; 54 : 65414888 : i = p; 55 : 65414888 : p = parent(p); 56 : : } 57 : 47322946 : heap [i] = x; 58 : 47322946 : indices[x] = i; 59 : 47322946 : } 60 : : 61 : : 62 : 16074229 : void percolateDown(int i) 63 : : { 64 : 16074229 : int x = heap[i]; 65 [ + + ]: 66426230 : while (left(i) < heap.size()){ 66 [ + + ][ + + ]: 62454670 : int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i); 67 [ + + ]: 62454670 : if (!lt(heap[child], x)) break; 68 : 50352003 : heap[i] = heap[child]; 69 : 50352003 : indices[heap[i]] = i; 70 : 50352003 : i = child; 71 : : } 72 : 16074229 : heap [i] = x; 73 : 16074229 : indices[x] = i; 74 : 16074229 : } 75 : : 76 : : 77 : : public: 78 : 103866 : Heap(const Comp& c) : lt(c) { } 79 : : 80 : 3384 : int size () const { return heap.size(); } 81 : 13584665 : bool empty () const { return heap.size() == 0; } 82 [ + + ][ + + ]: 282687220 : bool inHeap (int n) const { return n < indices.size() && indices[n] >= 0; } 83 : 0 : int operator[](int index) const 84 : : { 85 : 0 : Assert(index < heap.size()); 86 : 0 : return heap[index]; 87 : : } 88 : : 89 : 31414600 : void decrease(int n) 90 : : { 91 [ - + ][ - + ]: 31414600 : Assert(inHeap(n)); [ - - ] 92 : 31414600 : percolateUp(indices[n]); 93 : 31414600 : } 94 : 460112 : void increase(int n) 95 : : { 96 [ - + ][ - + ]: 460112 : Assert(inHeap(n)); [ - - ] 97 : 460112 : percolateDown(indices[n]); 98 : 460112 : } 99 : : 100 : : // Safe variant of insert/decrease/increase: 101 : 126650 : void update(int n) 102 : : { 103 [ + + ]: 126650 : if (!inHeap(n)) 104 : 2009 : insert(n); 105 : : else { 106 : 124641 : percolateUp(indices[n]); 107 : 124641 : percolateDown(indices[n]); } 108 : 126650 : } 109 : : 110 : : 111 : 15783705 : void insert(int n) 112 : : { 113 : 15783705 : indices.growTo(n+1, -1); 114 [ - + ][ - + ]: 15783705 : Assert(!inHeap(n)); [ - - ] 115 : : 116 : 15783705 : indices[n] = heap.size(); 117 : 15783705 : heap.push(n); 118 : 15783705 : percolateUp(indices[n]); 119 : 15783705 : } 120 : : 121 : : 122 : 13404998 : int removeMin() 123 : : { 124 : 13404998 : int x = heap[0]; 125 : 13404998 : heap[0] = heap.last(); 126 : 13404998 : indices[heap[0]] = 0; 127 : 13404998 : indices[x] = -1; 128 : 13404998 : heap.pop(); 129 [ + + ]: 13404998 : if (heap.size() > 1) percolateDown(0); 130 : 13404998 : return x; 131 : : } 132 : : 133 : : 134 : : // Rebuild the heap from scratch, using the elements in 'ns': 135 : 56831 : void build(vec<int>& ns) { 136 [ + + ]: 5051690 : for (int i = 0; i < heap.size(); i++) 137 : 4994860 : indices[heap[i]] = -1; 138 : 56831 : heap.clear(); 139 : : 140 [ + + ]: 4435820 : for (int i = 0; i < ns.size(); i++){ 141 : 4378990 : indices[ns[i]] = i; 142 : 4378990 : heap.push(ns[i]); } 143 : : 144 [ + + ]: 2238090 : for (int i = heap.size() / 2 - 1; i >= 0; i--) 145 : 2181260 : percolateDown(i); 146 : 56831 : } 147 : : 148 : 0 : void clear(bool dealloc = false) 149 : : { 150 [ - - ]: 0 : for (int i = 0; i < heap.size(); i++) 151 : 0 : indices[heap[i]] = -1; 152 : 0 : heap.clear(dealloc); 153 : 0 : } 154 : : }; 155 : : 156 : : 157 : : //================================================================================================= 158 : : } 159 : : } // namespace cvc5::internal 160 : : 161 : : #endif