HOG2
OpenListB.h
Go to the documentation of this file.
1 /*
2  * $Id: OpenListB.h
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 1/14/06.
6  * Modified by Nathan Sturtevant on 02/29/20.
7  *
8  * This file is part of HOG2. See https://github.com/nathansttt/hog2 for licensing information.
9  *
10  * Modified by Zhifu Zhang
11  *
12  */
13 
14 #ifndef OpenListB_H
15 #define OpenListB_H
16 
17 #include <cassert>
18 #include <vector>
19 #include <deque>
20 #include <unordered_map>
21 
27 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
28 class OpenListB {
29 public:
30  OpenListB();
31  ~OpenListB();
32  void reset();
33  void Add(OBJ val);
34  void DecreaseKey(OBJ val);
35  void IncreaseKey(OBJ val);
36  bool IsIn(OBJ val);
37  OBJ Remove();
38  void pop() { Remove(); }
39  OBJ top() { return _elts[0]; }
40  OBJ find(OBJ val);
41  bool Empty();
42  unsigned size() { return _elts.size(); }
43 // void verifyData();
44  OBJ FindSpecialMin(double F);
45  OBJ FindTieFMin(double F);
46 
47 private:
48  std::vector<OBJ> _elts;
49  void HeapifyUp(unsigned int index);
50  void HeapifyDown(unsigned int index);
51  typedef std::unordered_map<OBJ, unsigned int, HashKey, EqKey > IndexTable;
53 };
54 
55 
56 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
58 {
59 }
60 
61 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
63 {
64 }
65 
69 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
71 {
72  table.clear();
73  _elts.resize(0);
74 }
75 
79 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
81 {
82  assert(table.find(val) == table.end());
83  table[val] = _elts.size();
84  // val->key = count;
85  _elts.push_back(val);
86  //count++;
87  // HeapifyUp(val->key);
88  HeapifyUp(table[val]);
89 }
90 
94 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
96 {
97  EqKey eq;
98  assert(eq(_elts[table[val]], val));
99  //HeapifyUp(val->key);
100  _elts[table[val]] = val;
101  HeapifyUp(table[val]);
102 }
103 
107 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
109 {
110  EqKey eq;
111  assert(eq(_elts[table[val]], val));
112  _elts[table[val]] = val;
113  HeapifyDown(table[val]);
114 }
115 
119 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
121 {
122  EqKey eq;
123  if ((table.find(val) != table.end()) && (table[val] < _elts.size()) &&
124  (eq(_elts[table[val]], val)))
125  return true;
126  return false;
127 }
128 
132 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
134 {
135  if (Empty())
136  return OBJ();
137  // count--;
138  OBJ ans = _elts[0];
139  _elts[0] = _elts[_elts.size()-1];
140  table[_elts[0]] = 0;
141  //_elts[0]->key = 0;
142  _elts.pop_back();
143  table.erase(ans);
144  HeapifyDown(0);
145 
146  return ans;
147 }
148 
152 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
154 {
155  if (!IsIn(val))
156  return OBJ();
157  return _elts[table[val]];
158 }
159 
163 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
165 {
166  return _elts.size() == 0;
167 }
168 
170 //* Verify that the Heap is internally consistent. Fails assertion if not.
171 // */
172 //template<typename OBJ, class HashKey, class EqKey, class CmpKey>
173 //void OpenListB<OBJ, HashKey, EqKey, CmpKey>::verifyData()
174 //{
175 // assert(_elts.size() == table.size());
176 // OpenListB::IndexTable::iterator iter;
177 // for (iter = table.begin(); iter != table.end(); iter++)
178 // {
179 // EqKey eq;
180 // assert(eq(iter->first, _elts[iter->second]));
181 // }
182 //}
183 
184 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
186 {
187  if (index == 0) return;
188  int parent = (index-1)/2;
189  CmpKey compare;
190 
191  if (compare(_elts[parent], _elts[index]))
192  {
193  OBJ tmp = _elts[parent];
194  _elts[parent] = _elts[index];
195  _elts[index] = tmp;
196  table[_elts[parent]] = parent;
197  table[_elts[index]] = index;
198  EqKey eq;
199  assert(!eq(_elts[parent], _elts[index]));
200  HeapifyUp(parent);
201  }
202 }
203 
204 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
206 {
207  CmpKey compare;
208  unsigned int child1 = index*2+1;
209  unsigned int child2 = index*2+2;
210  int which;
211  unsigned int count = _elts.size();
212  // find smallest child
213  if (child1 >= count)
214  return;
215  else if (child2 >= count)
216  which = child1;
217  //else if (fless(_elts[child1]->GetKey(), _elts[child2]->GetKey()))
218  else if (!(compare(_elts[child1], _elts[child2])))
219  which = child1;
220  else
221  which = child2;
222 
223  //if (fless(_elts[which]->GetKey(), _elts[index]->GetKey()))
224  if (!(compare(_elts[which], _elts[index])))
225  {
226  OBJ tmp = _elts[which];
227  _elts[which] = _elts[index];
228  table[_elts[which]] = which;
229  _elts[index] = tmp;
230  table[_elts[index]] = index;
231 // _elts[which]->key = which;
232 // _elts[index]->key = index;
233  HeapifyDown(which);
234  }
235 }
236 
237 /* returns the index of the element that is in the special case, and has min special key */
238 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
240 {
241  std::deque<unsigned int> candidates;
242  CmpKeyStrictExtract extractor;
243  SpecialKey spk;
244 
245  if (!fless(extractor(_elts[0]), F))
246  return OBJ();
247 
248  unsigned int resultIndex = 0;
249  candidates.push_back(0);
250 
251  while(candidates.size())
252  {
253  unsigned int current = candidates.front();
254  candidates.pop_front();
255 
256  if (spk(_elts[resultIndex],_elts[current]))
257  {
258  resultIndex = current;
259  }
260 
261  unsigned int count = _elts.size();
262 
263  unsigned int child1 = current*2+1;
264  unsigned int child2 = current*2+2;
265 
266  if (child1 < count && fless(extractor(_elts[child1]),F))
267  {
268  candidates.push_back(child1);
269  }
270 
271  if (child2 < count && fless(extractor(_elts[child2]),F))
272  {
273  candidates.push_back(child2);
274  }
275  }
276 
277  return _elts[resultIndex];
278 }
279 
280 /* returns the index of the element that has f==F, and has min g, as suggested by Nathan */
281 template<typename OBJ, class HashKey, class EqKey, class CmpKey, class SpecialKey, class CmpKeyStrictExtract>
283 {
284  std::deque<unsigned int> candidates;
285  CmpKeyStrictExtract extractor;
286  SpecialKey spk;
287 
288  if (!fequal(extractor(_elts[0]), F))
289  return OBJ();
290 
291  unsigned int resultIndex = 0;
292  candidates.push_back(0);
293 
294  while(candidates.size())
295  {
296  unsigned int current = candidates.front();
297  candidates.pop_front();
298 
299  if (spk(_elts[resultIndex],_elts[current]))
300  {
301  resultIndex = current;
302  }
303 
304  unsigned int count = _elts.size();
305 
306  unsigned int child1 = current*2+1;
307  unsigned int child2 = current*2+2;
308 
309  if (child1 < count && fequal(extractor(_elts[child1]),F))
310  {
311  candidates.push_back(child1);
312  }
313 
314  if (child2 < count && fequal(extractor(_elts[child2]),F))
315  {
316  candidates.push_back(child2);
317  }
318  }
319 
320  return _elts[resultIndex];
321 }
322 
323 
324 #endif
OpenListB::HeapifyUp
void HeapifyUp(unsigned int index)
‍**
Definition: OpenListB.h:185
OpenListB::Empty
bool Empty()
Returns true if no items are in the OpenListB.
Definition: OpenListB.h:164
OpenListB::Add
void Add(OBJ val)
Add object into OpenListB.
Definition: OpenListB.h:80
OpenListB::find
OBJ find(OBJ val)
find this object in the Heap and return
Definition: OpenListB.h:153
OpenListB::pop
void pop()
Definition: OpenListB.h:38
OpenListB::IsIn
bool IsIn(OBJ val)
Returns true if the object is in the OpenListB.
Definition: OpenListB.h:120
OpenListB::FindTieFMin
OBJ FindTieFMin(double F)
Definition: OpenListB.h:282
OpenListB::top
OBJ top()
Definition: OpenListB.h:39
OpenListB::~OpenListB
~OpenListB()
Definition: OpenListB.h:62
fless
bool fless(double a, double b)
Definition: FPUtil.h:28
OpenListB::_elts
std::vector< OBJ > _elts
Definition: OpenListB.h:48
OpenListB
A simple & efficient Heap class.
Definition: OpenListB.h:28
OpenListB::size
unsigned size()
Definition: OpenListB.h:42
OpenListB::FindSpecialMin
OBJ FindSpecialMin(double F)
Definition: OpenListB.h:239
OpenListB::HeapifyDown
void HeapifyDown(unsigned int index)
Definition: OpenListB.h:205
OpenListB::table
IndexTable table
Definition: OpenListB.h:52
OpenListB::IndexTable
std::unordered_map< OBJ, unsigned int, HashKey, EqKey > IndexTable
Definition: OpenListB.h:51
OpenListB::IncreaseKey
void IncreaseKey(OBJ val)
Indicate that the key for a particular object has increased.
Definition: OpenListB.h:108
OpenListB::DecreaseKey
void DecreaseKey(OBJ val)
Indicate that the key for a particular object has decreased.
Definition: OpenListB.h:95
fequal
bool fequal(double a, double b, double tolerance=TOLERANCE)
Definition: FPUtil.h:32
OpenListB::Remove
OBJ Remove()
Remove the item with the lowest key from the OpenListB & re-heapify.
Definition: OpenListB.h:133
OpenListB::OpenListB
OpenListB()
Definition: OpenListB.h:57
OpenListB::reset
void reset()
Remove all objects from queue.
Definition: OpenListB.h:70