CVC3
|
00001 /*****************************************************************************/ 00002 /*! 00003 *\file minisat_heap.h 00004 *\brief MiniSat internal heap implementation 00005 * 00006 * Author: Alexander Fuchs 00007 * 00008 * Created: Fri Sep 08 11:04:00 2006 00009 * 00010 * <hr> 00011 * 00012 * License to use, copy, modify, sell and/or distribute this software 00013 * and its documentation for any purpose is hereby granted without 00014 * royalty, subject to the terms and conditions defined in the \ref 00015 * LICENSE file provided with this distribution. 00016 * 00017 * <hr> 00018 */ 00019 /*****************************************************************************/ 00020 00021 /******************************************************************************************[Heap.h] 00022 MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson 00023 00024 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 00025 associated documentation files (the "Software"), to deal in the Software without restriction, 00026 including without limitation the rights to use, copy, modify, merge, publish, distribute, 00027 sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00028 furnished to do so, subject to the following conditions: 00029 00030 The above copyright notice and this permission notice shall be included in all copies or 00031 substantial portions of the Software. 00032 00033 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 00034 NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00035 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00036 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 00037 OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00038 **************************************************************************************************/ 00039 00040 #ifndef _cvc3__minisat__heap_h_ 00041 #define _cvc3__minisat__heap_h_ 00042 00043 //================================================================================================= 00044 00045 #include "debug.h" 00046 #include <iostream> 00047 00048 // provides a heap over ints 00049 00050 namespace MiniSat { 00051 00052 00053 static inline int left (int i) { return i+i; } 00054 static inline int right (int i) { return i+i + 1; } 00055 static inline int parent(int i) { return i >> 1; } 00056 00057 template<class C> 00058 class Heap { 00059 public: 00060 C comp; 00061 vec<int> heap; // heap of ints 00062 vec<int> indices; // int -> index in heap 00063 00064 inline void percolateUp(int i) 00065 { 00066 int x = heap[i]; 00067 while (parent(i) != 0 && comp(x,heap[parent(i)])){ 00068 heap[i] = heap[parent(i)]; 00069 indices[heap[i]] = i; 00070 i = parent(i); 00071 } 00072 heap [i] = x; 00073 indices[x] = i; 00074 } 00075 00076 inline void percolateDown(int i) 00077 { 00078 int x = heap[i]; 00079 while (left(i) < heap.size()){ 00080 int child = right(i) < heap.size() && comp(heap[right(i)],heap[left(i)]) ? right(i) : left(i); 00081 if (!comp(heap[child],x)) break; 00082 heap[i] = heap[child]; 00083 indices[heap[i]] = i; 00084 i = child; 00085 } 00086 heap [i] = x; 00087 indices[x] = i; 00088 } 00089 00090 bool ok(int n) { return n >= 0 && n < (int)indices.size(); } 00091 00092 public: 00093 Heap(C c) : comp(c) { heap.push(-1); } 00094 00095 void setBounds (int size) { DebugAssert(size >= 0, "MiniSat::Heap::setBounds"); indices.growTo(size,0); } 00096 bool inHeap (int n) { DebugAssert(ok(n), "MiniSat::Heap::inHeap"); return indices[n] != 0; } 00097 00098 void increase (int n){ 00099 DebugAssert(ok(n), "MiniSat::Heap::increase: ok"); 00100 DebugAssert(inHeap(n), "MiniSat::Heap::increase: inHeap"); 00101 percolateUp(indices[n]); 00102 } 00103 00104 bool empty () { return heap.size() == 1; } 00105 00106 void insert(int n) { 00107 DebugAssert(n > 0, "MiniSat::Heap::insert: inserting invalid var id"); 00108 if (!inHeap(n)) { 00109 DebugAssert(ok(n), "MiniSat::Heap::insert: ok"); 00110 indices[n] = heap.size(); 00111 heap.push(n); 00112 percolateUp(indices[n]); 00113 } 00114 } 00115 00116 int getMin() { 00117 int r = heap[1]; 00118 DebugAssert(r > 0, "MiniSatHeap:getmin: invalid var id"); 00119 heap[1] = heap.last(); 00120 indices[heap[1]] = 1; 00121 indices[r] = 0; 00122 heap.pop(); 00123 if (heap.size() > 1) 00124 percolateDown(1); 00125 return r; } 00126 00127 bool heapProperty() { 00128 return heapProperty(1); } 00129 00130 bool heapProperty(int i) { 00131 return (size_t)i >= heap.size() 00132 || ((parent(i) == 0 || !comp(heap[i],heap[parent(i)])) && heapProperty(left(i)) && heapProperty(right(i))); } 00133 }; 00134 00135 } 00136 00137 //================================================================================================= 00138 #endif