HOG2
BDOpenClosed.h
Go to the documentation of this file.
1 /*
2  * BDOpenClosed.h
3  */
4 
5 #ifndef BDOPENCLOSED_H
6 #define BDOPENCLOSED_H
7 
8 #include <cassert>
9 #include <vector>
10 #include <unordered_map>
11 #include <stdint.h>
12 #include <unordered_map>
13 #include "AStarOpenClosed.h"
14 
15 //#define ADMISSIBLE
16 //struct AHash64 {
17 // size_t operator()(const uint64_t &x) const
18 // { return (size_t)(x); }
19 //};
20 
21 
23  kOpenReady = 0,//priority queue 0, low g -> low f
24  kOpenWaiting = 1,//priority queue 1, low f -> low g
27 };
28 
29 
30 const uint64_t kTBDNoNode = 0xFFFFFFFFFFFFFFFFull;
31 
32 template<typename state>
34 public:
36  BDOpenClosedData(const state &theData, double gCost, double hCost, uint64_t parent, uint64_t openLoc, stateLocation location)
37  :data(theData), g(gCost), h(hCost), parentID(parent), openLocation(openLoc), where(location) { reopened = false; }
38  state data;
39  double g;
40  double h;
41  uint64_t parentID;
42  uint64_t openLocation;
43  bool reopened;
45 };
46 
47 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure = BDOpenClosedData<state> >
48 class BDOpenClosed {
49 public:
50  BDOpenClosed();
51  ~BDOpenClosed();
52  void Reset(int);
53  uint64_t AddOpenNode(const state &val, uint64_t hash, double g, double h, uint64_t parent=kTBDNoNode, stateLocation whichQueue = kOpenWaiting);
54  uint64_t AddClosedNode(state &val, uint64_t hash, double g, double h, uint64_t parent=kTBDNoNode);
55  void KeyChanged(uint64_t objKey);
56  void Remove(uint64_t objKey);
57  //void IncreaseKey(uint64_t objKey);
58  stateLocation Lookup(uint64_t hashKey, uint64_t &objKey) const;
59  inline dataStructure &Lookup(uint64_t objKey) { return elements[objKey]; }
60  inline const dataStructure &Lookat(uint64_t objKey) const { return elements[objKey]; }
61  uint64_t Peek(stateLocation whichQueue) const;
62  inline const dataStructure &PeekAt(stateLocation whichQueue) const;
63 
64  //if exist min pair, return true, else(one queue is empty) return false;
65  //if it returns true, left and right should be set to the pair that is supposed to be returned.
66  //bool ExtractMinPair(uint64_t& left, uint64_t& right) ;
67  uint64_t Close();
68  uint64_t PutToReady();
69  //void Reopen(uint64_t objKey);
70 #ifdef ADMISSIBLE
71  void Reopen(uint64_t objKey);
72 #endif // ADMISSIBLE
73 
74 
75  uint64_t GetOpenItem(unsigned int which, stateLocation where){ return priorityQueues[where][which];}
76  size_t OpenReadySize() const { return priorityQueues[kOpenReady].size(); }
77  size_t OpenWaitingSize() const { return priorityQueues[kOpenWaiting].size(); }
78  size_t OpenSize() const { return priorityQueues[kOpenReady].size()+priorityQueues[kOpenWaiting].size(); }
79 
80  size_t ClosedSize() const { return size()-OpenReadySize()-OpenWaitingSize(); }
81  size_t size() const { return elements.size(); }
82  void verifyData();
83  bool ValidateOpenReady(int index = 0)
84  {
85  stateLocation whichQ = kOpenReady;
86  CmpKey0 compare;
87  if (index >= priorityQueues[whichQ].size())
88  return true;
89  int child1 = index * 2 + 1;
90  int child2 = index * 2 + 2;
91  if (priorityQueues[whichQ].size() > child1 &&
92  !compare(elements[priorityQueues[whichQ][child1]], elements[priorityQueues[whichQ][index]]))
93  return false;
94  if (priorityQueues[whichQ].size() > child2 &&
95  !compare(elements[priorityQueues[whichQ][child2]], elements[priorityQueues[whichQ][index]]))
96  return false;
97  return ValidateOpenReady(child1) && ValidateOpenReady(child2);
98  }
99 
100  bool ValidateOpenWaiting(int index = 0)
101  {
102  stateLocation whichQ = kOpenWaiting;
103  CmpKey1 compare;
104  if (index >= priorityQueues[whichQ].size())
105  return true;
106  int child1 = index * 2 + 1;
107  int child2 = index * 2 + 2;
108  if (priorityQueues[whichQ].size() > child1 &&
109  !compare(elements[priorityQueues[whichQ][child1]], elements[priorityQueues[whichQ][index]]))
110  return false;
111  if (priorityQueues[whichQ].size() > child2 &&
112  !compare(elements[priorityQueues[whichQ][child2]], elements[priorityQueues[whichQ][index]]))
113  return false;
114  return ValidateOpenWaiting(child1) && ValidateOpenWaiting(child2);
115  }
116 private:
117  bool HeapifyUp(unsigned int index, stateLocation whichQueue);
118  void HeapifyDown(unsigned int index, stateLocation whichQueue);
119 
120  //2 queues:
121  //priorityQueues[0] is openReady, priorityQueues[1] is openWaiting
122  std::vector<std::vector<uint64_t>> priorityQueues;
123  //std::vector<uint64_t> readyQueue;
124  //std::vector<uint64_t> waitingQueue;
125 
126  // storing the element id; looking up with hash
127  std::unordered_map<uint64_t, size_t> table;
128  //all the elements, open or closed
129  std::vector<dataStructure> elements;
130 };
131 
132 #ifdef ADMISSIBLE
133 
134 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
136 {
137  assert(elements[objKey].where == kClosed);
138  elements[objKey].reopened = true;
139  elements[objKey].where = kOpenWaiting;
140  elements[objKey].openLocation = priorityQueues[kOpenWaiting].size();
141  priorityQueues[kOpenWaiting].push_back(objKey);
142  HeapifyUp(priorityQueues[kOpenWaiting].size() - 1, kOpenWaiting);
143 }
144 
145 #endif // ADMISSIBLE
146 
147 
148 
149 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
151 {
152  std::vector<uint64_t> queue;
153  queue.resize(0);
154  priorityQueues.push_back(queue);
155  priorityQueues.push_back(queue);
156  //readyQueue.resize(0);
157  //waitingQueue.resize(0);
158 }
159 
160 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
162 {
163 }
164 
168 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
170 {
171  table.clear();
172  elements.clear();
173  priorityQueues[0].resize(0);
174  priorityQueues[1].resize(0);
175  //readyQueue.resize(0);
176  //waitingQueue.resize(0);
177 }
178 
182 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
183 uint64_t BDOpenClosed<state, CmpKey0, CmpKey1, dataStructure>::AddOpenNode(const state &val, uint64_t hash, double g, double h, uint64_t parent, stateLocation whichQueue)
184 {
185  // should do lookup here...
186  if (table.find(hash) != table.end())
187  {
188  //return -1; // TODO: find correct id and return
189  assert(false);
190  }
191  if (whichQueue == kOpenReady)
192  {
193  elements.push_back(dataStructure(val, g, h, parent, priorityQueues[0].size() , kOpenReady));
194 
195  }
196  else if (whichQueue == kOpenWaiting)
197  {
198  elements.push_back(dataStructure(val, g, h, parent, priorityQueues[1].size(), kOpenWaiting));
199  }
200 
201  if (parent == kTBDNoNode)
202  elements.back().parentID = elements.size()-1;
203  table[hash] = elements.size()-1; // hashing to element list location
204 
205  priorityQueues[whichQueue].push_back(elements.size() - 1);
206  HeapifyUp(priorityQueues[whichQueue].size() - 1,whichQueue);
207 
208  return elements.size()-1;
209 }
210 
214 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
215 uint64_t BDOpenClosed<state, CmpKey0, CmpKey1, dataStructure>::AddClosedNode(state &val, uint64_t hash, double g, double h, uint64_t parent)
216 {
217  // should do lookup here...
218  assert(table.find(hash) == table.end());
219  elements.push_back(dataStructure(val, g, h, parent, 0, kClosed));
220  if (parent == kTBDNoNode)
221  elements.back().parentID = elements.size()-1;
222  table[hash] = elements.size()-1; // hashing to element list location
223  return elements.size()-1;
224 }
225 
229 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
231 {
232 // EqKey eq;
233 // assert(eq(waitingQueue[table[val]], val));
234 // //HeapifyUp(val->key);
235 // waitingQueue[table[val]] = val;
236  if (elements[val].where == kOpenReady)
237  {
238  if (!HeapifyUp(elements[val].openLocation, kOpenReady))
239  HeapifyDown(elements[val].openLocation, kOpenReady);
240  }
241  else if (elements[val].where == kOpenWaiting)
242  {
243  if (!HeapifyUp(elements[val].openLocation, kOpenWaiting))
244  HeapifyDown(elements[val].openLocation, kOpenWaiting);
245  }
246 }
247 
248 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
250 {
251 
252  int index = elements[val].openLocation;
253  stateLocation whichQueue = elements[val].where;
254  elements[val].where = kClosed;
255  priorityQueues[whichQueue][index] = priorityQueues[whichQueue][priorityQueues[whichQueue].size() - 1];
256  elements[priorityQueues[whichQueue][index]].openLocation = index;
257  priorityQueues[whichQueue].pop_back();
258 
259  if (!HeapifyUp(index, whichQueue))
260  HeapifyDown(index, whichQueue);
261 
262 
263 }
264 
266 // * Indicate that the key for a particular object has increased.
267 // */
268 //template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
269 //void BDOpenClosed<state, CmpKey0, CmpKey1, dataStructure>::IncreaseKey(uint64_t val)
270 //{
274 // HeapifyDown(val);
275 //}
276 
281 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
283 {
284  auto it = table.find(hashKey);
285  if (it == table.end())
286  return kUnseen;
287 
288  objKey = it->second;
289  return elements[objKey].where;
290 }
291 
292 
296 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
298 {
299  if (whichQueue == kOpenReady)
300  {
301  assert(OpenReadySize() != 0);
302  }
303  else if (whichQueue == kOpenWaiting)
304  {
305  assert(OpenWaitingSize() != 0);
306  }
307  return priorityQueues[whichQueue][0];
308 }
309 
313 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
315 {
316  if (whichQueue == kOpenReady)
317  {
318  assert(OpenReadySize() != 0);
319  }
320  else if (whichQueue == kOpenWaiting)
321  {
322  assert(OpenWaitingSize() != 0);
323  }
324  return elements[priorityQueues[whichQueue][0]];
325 }
326 
327 
328 
332 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
334 {
335  assert(OpenReadySize() != 0);
336 
337  uint64_t ans = priorityQueues[0][0];
338  elements[ans].where = kClosed;
339  priorityQueues[0][0] = priorityQueues[0][OpenReadySize()-1];
340  elements[priorityQueues[0][0]].openLocation = 0;
341  priorityQueues[0].pop_back();
342 
343  HeapifyDown(0,kOpenReady);
344 
345  return ans;
346 }
347 
348 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
350 {
351  assert(OpenWaitingSize() != 0);
352 
353 
354  //remove it from openWaiting
355  uint64_t ans = priorityQueues[kOpenWaiting][0];
356  uint64_t back = priorityQueues[kOpenWaiting].back();
357  priorityQueues[kOpenWaiting][0] = back;
358  priorityQueues[kOpenWaiting].pop_back();
359  elements[back].openLocation = 0;
360 
361  HeapifyDown(0, kOpenWaiting);
362 // assert(ValidateOpenReady());
363 // assert(ValidateOpenWaiting());
364 
365  //put it to openReady
366  priorityQueues[kOpenReady].push_back(ans);
367  elements[ans].where = kOpenReady;
368  elements[ans].openLocation = priorityQueues[kOpenReady].size()-1;
369 
370  HeapifyUp(priorityQueues[kOpenReady].size() - 1,kOpenReady);
371 
372 // assert(ValidateOpenReady());
373 // assert(ValidateOpenWaiting());
374 
375  return ans;
376 }
377 
381 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
383 {
384  if (index == 0) return false;
385  int parent = (index-1)/2;
386 
387  if (whichQueue == kOpenReady)
388  {
389  CmpKey0 compare;
390  if (compare(elements[priorityQueues[whichQueue][parent]], elements[priorityQueues[whichQueue][index]]))
391  {
392  unsigned int tmp = priorityQueues[whichQueue][parent];
393  priorityQueues[whichQueue][parent] = priorityQueues[whichQueue][index];
394  priorityQueues[whichQueue][index] = tmp;
395  elements[priorityQueues[whichQueue][parent]].openLocation = parent;
396  elements[priorityQueues[whichQueue][index]].openLocation = index;
397  HeapifyUp(parent, whichQueue);
398  return true;
399  }
400  }
401  else if (whichQueue == kOpenWaiting)
402  {
403  CmpKey1 compare;
404  if (compare(elements[priorityQueues[whichQueue][parent]], elements[priorityQueues[whichQueue][index]]))
405  {
406  unsigned int tmp = priorityQueues[whichQueue][parent];
407  priorityQueues[whichQueue][parent] = priorityQueues[whichQueue][index];
408  priorityQueues[whichQueue][index] = tmp;
409  elements[priorityQueues[whichQueue][parent]].openLocation = parent;
410  elements[priorityQueues[whichQueue][index]].openLocation = index;
411  HeapifyUp(parent, whichQueue);
412  return true;
413  }
414  }
415 
416 
417  return false;
418 }
419 
420 template<typename state, typename CmpKey0, typename CmpKey1, class dataStructure>
422 {
423 
424  unsigned int child1 = index*2+1;
425  unsigned int child2 = index*2+2;
426 
427 
428 
429  if (whichQueue == kOpenReady)
430  {
431  CmpKey0 compare;
432  int which;
433  unsigned int count = priorityQueues[whichQueue].size();
434  // find smallest child
435  if (child1 >= count)
436  return;
437  else if (child2 >= count)
438  which = child1;
439  else if (!(compare(elements[priorityQueues[whichQueue][child1]], elements[priorityQueues[whichQueue][child2]])))
440  which = child1;
441  else
442  which = child2;
443 
444  //if (fless(waitingQueue[which]->GetKey(), waitingQueue[index]->GetKey()))
445  if (!(compare(elements[priorityQueues[whichQueue][which]], elements[priorityQueues[whichQueue][index]])))
446  {
447  unsigned int tmp = priorityQueues[whichQueue][which];
448  priorityQueues[whichQueue][which] = priorityQueues[whichQueue][index];
449  // table[waitingQueue[which]] = which;
450  priorityQueues[whichQueue][index] = tmp;
451  elements[priorityQueues[whichQueue][which]].openLocation = which;
452  elements[priorityQueues[whichQueue][index]].openLocation = index;
453  // table[waitingQueue[index]] = index;
454  // waitingQueue[which]->key = which;
455  // waitingQueue[index]->key = index;
456  HeapifyDown(which,whichQueue);
457  }
458  }
459  else if (whichQueue == kOpenWaiting)
460  {
461  CmpKey1 compare;
462  int which;
463  unsigned int count = priorityQueues[whichQueue].size();
464  // find smallest child
465  if (child1 >= count) // no children; done
466  return;
467  else if (child2 >= count) // one child - compare there
468  which = child1;
469  // find larger child to move up
470  else if (!(compare(elements[priorityQueues[whichQueue][child1]], elements[priorityQueues[whichQueue][child2]])))
471  which = child1;
472  else
473  which = child2;
474 
475  //if (fless(waitingQueue[which]->GetKey(), waitingQueue[index]->GetKey()))
476  if (!(compare(elements[priorityQueues[whichQueue][which]], elements[priorityQueues[whichQueue][index]])))
477  {
478  unsigned int tmp = priorityQueues[whichQueue][which];
479  priorityQueues[whichQueue][which] = priorityQueues[whichQueue][index];
480  priorityQueues[whichQueue][index] = tmp;
481 
482 // assert(elements[priorityQueues[whichQueue][which]].where == kOpenWaiting);
483 // assert(elements[priorityQueues[whichQueue][index]].where == kOpenWaiting);
484  elements[priorityQueues[whichQueue][which]].openLocation = which;
485  elements[priorityQueues[whichQueue][index]].openLocation = index;
486  HeapifyDown(which, whichQueue);
487 // assert((compare(elements[priorityQueues[whichQueue][which]], elements[priorityQueues[whichQueue][index]])));
488 // if (child1 < count)
489 // assert((compare(elements[priorityQueues[whichQueue][child1]], elements[priorityQueues[whichQueue][index]])));
490 // if (child2 < count)
491 // {
492 // printf("w:%d - c1:%d c2:%d\n", which, child1, child2);
493 // assert((compare(elements[priorityQueues[whichQueue][child2]], elements[priorityQueues[whichQueue][index]])));
494 // }
495  }
496  }
497 
498 }
499 
500 #endif
kOpenWaiting
@ kOpenWaiting
Definition: BDOpenClosed.h:24
BDOpenClosed::verifyData
void verifyData()
BDOpenClosed::ValidateOpenWaiting
bool ValidateOpenWaiting(int index=0)
Definition: BDOpenClosed.h:100
BDOpenClosedData::parentID
uint64_t parentID
Definition: BDOpenClosed.h:41
BDOpenClosed::AddOpenNode
uint64_t AddOpenNode(const state &val, uint64_t hash, double g, double h, uint64_t parent=kTBDNoNode, stateLocation whichQueue=kOpenWaiting)
Add object into open list.
Definition: BDOpenClosed.h:183
BDOpenClosed::size
size_t size() const
Definition: BDOpenClosed.h:81
BDOpenClosed::Lookup
dataStructure & Lookup(uint64_t objKey)
Definition: BDOpenClosed.h:59
BDOpenClosed::Reset
void Reset(int)
Remove all objects from queue.
Definition: BDOpenClosed.h:169
kOpenReady
@ kOpenReady
Definition: BDOpenClosed.h:23
BDOpenClosed::Remove
void Remove(uint64_t objKey)
Definition: BDOpenClosed.h:249
AStarOpenClosed.h
BDOpenClosed::Lookup
stateLocation Lookup(uint64_t hashKey, uint64_t &objKey) const
‍**
Definition: BDOpenClosed.h:282
BDOpenClosed::KeyChanged
void KeyChanged(uint64_t objKey)
Indicate that the key for a particular object has changed.
Definition: BDOpenClosed.h:230
kClosed
@ kClosed
Definition: BDOpenClosed.h:25
BDOpenClosedData::h
double h
Definition: BDOpenClosed.h:40
BDOpenClosed::elements
std::vector< dataStructure > elements
Definition: BDOpenClosed.h:129
BDOpenClosed::HeapifyUp
bool HeapifyUp(unsigned int index, stateLocation whichQueue)
Moves a node up the heap.
Definition: BDOpenClosed.h:382
BDOpenClosedData::data
state data
Definition: BDOpenClosed.h:38
BDOpenClosed::ClosedSize
size_t ClosedSize() const
Definition: BDOpenClosed.h:80
BDOpenClosed::table
std::unordered_map< uint64_t, size_t > table
Definition: BDOpenClosed.h:127
BDOpenClosedData::BDOpenClosedData
BDOpenClosedData(const state &theData, double gCost, double hCost, uint64_t parent, uint64_t openLoc, stateLocation location)
Definition: BDOpenClosed.h:36
BDOpenClosed::PeekAt
const dataStructure & PeekAt(stateLocation whichQueue) const
Peek at the next item to be expanded.
Definition: BDOpenClosed.h:314
kUnseen
@ kUnseen
Definition: BDOpenClosed.h:26
BDOpenClosed::HeapifyDown
void HeapifyDown(unsigned int index, stateLocation whichQueue)
Definition: BDOpenClosed.h:421
kTBDNoNode
const uint64_t kTBDNoNode
Definition: BDOpenClosed.h:30
BDOpenClosed::OpenReadySize
size_t OpenReadySize() const
Definition: BDOpenClosed.h:76
stateLocation
stateLocation
Definition: BDOpenClosed.h:22
BDOpenClosed::BDOpenClosed
BDOpenClosed()
Definition: BDOpenClosed.h:150
BDOpenClosedData::g
double g
Definition: BDOpenClosed.h:39
BDOpenClosed::PutToReady
uint64_t PutToReady()
Definition: BDOpenClosed.h:349
BDOpenClosedData
Definition: BDOpenClosed.h:33
BDOpenClosedData::reopened
bool reopened
Definition: BDOpenClosed.h:43
BDOpenClosedData::where
stateLocation where
Definition: BDOpenClosed.h:44
BDOpenClosed::AddClosedNode
uint64_t AddClosedNode(state &val, uint64_t hash, double g, double h, uint64_t parent=kTBDNoNode)
Add object into closed list.
Definition: BDOpenClosed.h:215
BDOpenClosed::Close
uint64_t Close()
Move the best item to the closed list and return key.
Definition: BDOpenClosed.h:333
BDOpenClosed::OpenSize
size_t OpenSize() const
Definition: BDOpenClosed.h:78
BDOpenClosed::OpenWaitingSize
size_t OpenWaitingSize() const
Definition: BDOpenClosed.h:77
BDOpenClosed::ValidateOpenReady
bool ValidateOpenReady(int index=0)
Definition: BDOpenClosed.h:83
BDOpenClosed::GetOpenItem
uint64_t GetOpenItem(unsigned int which, stateLocation where)
Definition: BDOpenClosed.h:75
BDOpenClosed::Peek
uint64_t Peek(stateLocation whichQueue) const
Peek at the next item to be expanded.
Definition: BDOpenClosed.h:297
BDOpenClosedData::BDOpenClosedData
BDOpenClosedData()
Definition: BDOpenClosed.h:35
BDOpenClosedData::openLocation
uint64_t openLocation
Definition: BDOpenClosed.h:42
BDOpenClosed
Definition: BDOpenClosed.h:48
BDOpenClosed::Lookat
const dataStructure & Lookat(uint64_t objKey) const
Definition: BDOpenClosed.h:60
BDOpenClosed::~BDOpenClosed
~BDOpenClosed()
Definition: BDOpenClosed.h:161
BDOpenClosed::priorityQueues
std::vector< std::vector< uint64_t > > priorityQueues
Definition: BDOpenClosed.h:122