HOG2
DynamicPotentialSearch.h
Go to the documentation of this file.
1 //
2 // DynamicPotentialSearch.h
3 // HOG2 Demos
4 //
5 // Created by Nathan Sturtevant on 5/24/16.
6 // Copyright © 2016 NS Software. All rights reserved.
7 //
8 
9 #ifndef DynamicPotentialSearch_h
10 #define DynamicPotentialSearch_h
11 
12 
13 #include <iostream>
14 #include "FPUtil.h"
15 #include <unordered_map>
16 #include "AStarOpenClosed.h"
17 #include "BucketOpenClosed.h"
18 #include "TemplateAStar.h"
19 //#include "SearchEnvironment.h" // for the SearchEnvironment class
20 #include "float.h"
21 #include <algorithm> // for vector reverse
22 #include "GenericSearchAlgorithm.h"
23 #include <unordered_map>
24 
28 //template <class state>
29 //struct DPSCompare {
30 // bool operator()(const AStarOpenClosedData<state> &i1, const AStarOpenClosedData<state> &i2) const
31 // {
32 // if (fequal(i1.g+i1.h, i2.g+i2.h))
33 // {
34 // return (fless(i1.g, i2.g));
35 // }
36 // return (fgreater(i1.g+i1.h, i2.g+i2.h));
37 // }
38 //};
39 template<typename state>
40 class DPSData {
41 public:
42  DPSData() {}
43  DPSData(const state &theData, double gCost, double hCost, const state &par)
44  :data(theData), g(gCost), h(hCost), parent(par), open(true), reopened(false) {}
45  state data;
46  double g;
47  double h;
48  state parent;
49  bool open;
50  bool reopened;
51 };
52 
53 
54 
55 template <class state, class action, class environment>
57 public:
60  void GetPath(environment *env, const state& from, const state& to, std::vector<state> &thePath);
61  void GetPath(environment *, const state& , const state& , std::vector<action> & );
62 
63 // AStarOpenClosed<state, AStarCompare<state>> open;
64  std::unordered_map<uint64_t, DPSData<state>> openClosed;
65  typename std::unordered_map<uint64_t, DPSData<state>>::const_iterator iter;
66  state goal, start;
67 
68  bool InitializeSearch(environment *env, const state& from, const state& to, std::vector<state> &thePath);
69  bool DoSingleSearchStep(std::vector<state> &thePath);
70 // void AddAdditionalStartState(state& newState);
71 // void AddAdditionalStartState(state& newState, double cost);
72 
73 // state CheckNextNode();
74  void ExtractPathToStart(const state &node, std::vector<state> &thePath)
75  {
76  thePath.push_back(node);
77  const auto &i = openClosed[env->GetStateHash(node)];
78  if (i.parent == node)
79  return;
80  ExtractPathToStart(i.parent, thePath);
81  }
82  const state &GetParent(const state &s);
83  virtual const char *GetName();
84 
85  void PrintStats();
86 // uint64_t GetUniqueNodesExpanded() { return uniqueNodesExpanded; }
88  int GetMemoryUsage();
89 
90  double GetBestFMin();
91  void ResetIterator();
92  bool GetNext(double &g, double &h);
93 
94 // bool GetClosedListGCost(const state &val, double &gCost) const;
95 // bool GetOpenListGCost(const state &val, double &gCost) const;
96 // bool GetClosedItem(const state &s, AStarOpenClosedData<state> &);
97 // unsigned int GetNumOpenItems() { return fhat.OpenSize(); }
98 // inline const AStarOpenClosedData<state> &GetOpenItem(unsigned int which) { return fhat.Lookat(fhat.GetOpenItem(which)); }
99 // inline const int GetNumItems() { return fhat.size(); }
100 // inline const AStarOpenClosedData<state> &GetItem(unsigned int which) { return fhat.Lookat(which); }
101 // bool HaveExpandedState(const state &val)
102 // { uint64_t key; return fhat.Lookup(env->GetStateHash(val), key) != kNotFound; }
103 // dataLocation GetStateLocation(const state &val)
104 // { uint64_t key; return fhat.Lookup(env->GetStateHash(val), key); }
105 
106  void SetReopenNodes(bool re) { reopenNodes = re; }
107  bool GetReopenNodes() { return reopenNodes; }
108 
110 
111  uint64_t GetNodesExpanded() const { return nodesExpanded; }
112  uint64_t GetNodesTouched() const { return nodesTouched; }
113 
114 // void LogFinalStats(StatCollection *) {}
115 
116  void OpenGLDraw() const;
117  void Draw(Graphics::Display &d) const;
118 
119 // void SetWeight(double w) {weight = w;}
120  void SetOptimalityBound(double w) {bound = w;}
121  double GetOptimalityBound() {return bound;}
122 private:
124 
125  std::vector<state> neighbors;
126 // std::vector<uint64_t> neighborID;
127 // std::vector<double> edgeCosts;
128 // std::vector<dataLocation> neighborLoc;
129  environment *env;
130  double bestSolution;
131  double weight;
132  double bound;
136 
137 };
138 
139 //static const bool verbose = false;
140 
149 template <class state, class action, class environment>
151 {
152  static char name[32];
153  sprintf(name, "DynamicPotentialSearch[%1.2f, %1.2f]", bound, weight);
154  return name;
155 }
156 
168 template <class state, class action, class environment>
169 void DynamicPotentialSearch<state,action,environment>::GetPath(environment *_env, const state& from, const state& to, std::vector<state> &thePath)
170 {
171  //discardcount=0;
172  if (!InitializeSearch(_env, from, to, thePath))
173  {
174  return;
175  }
176  while (!DoSingleSearchStep(thePath))
177  { }
178 }
179 
180 template <class state, class action, class environment>
181 void DynamicPotentialSearch<state,action,environment>::GetPath(environment *_env, const state& from, const state& to, std::vector<action> &path)
182 {
183  std::vector<state> thePath;
184  if (!InitializeSearch(_env, from, to, thePath))
185  {
186  return;
187  }
188  path.resize(0);
189  while (!DoSingleSearchStep(thePath))
190  { }
191  for (int x = 0; x < thePath.size()-1; x++)
192  {
193  path.push_back(_env->GetAction(thePath[x], thePath[x+1]));
194  }
195 }
196 
197 
208 template <class state, class action, class environment>
209 bool DynamicPotentialSearch<state,action,environment>::InitializeSearch(environment *_env, const state& from, const state& to, std::vector<state> &thePath)
210 {
211  bestSolution = DBL_MAX;
212 
213  if (theHeuristic == 0)
214  theHeuristic = _env;
215  thePath.resize(0);
216  env = _env;
217  openClosed.clear();
218  ResetNodeCount();
219  start = from;
220  goal = to;
221 
222  if (env->GoalTest(from, to)) //assumes that from and to are valid states
223  {
224  return false;
225  }
226  openClosed[env->GetStateHash(start)] = {start, 0, theHeuristic->HCost(start, goal), start};
227 
228  return true;
229 }
230 
232 // * Add additional start state to the search. This should only be called after Initialize Search and before DoSingleSearchStep.
233 // * @author Nathan Sturtevant
234 // * @date 01/06/08
235 // */
236 //template <class state, class action, class environment>
237 //void DynamicPotentialSearch<state,action,environment>::AddAdditionalStartState(state& newState)
238 //{
239 // fhat.AddOpenNode(newState, env->GetStateHash(newState), 0, weight*theHeuristic->HCost(start, goal));
240 // f.AddOpenNode(newState, env->GetStateHash(newState), 0, theHeuristic->HCost(start, goal));
241 //}
242 //
244 // * Add additional start state to the search. This should only be called after Initialize Search
245 // * @author Nathan Sturtevant
246 // * @date 09/25/10
247 // */
248 //template <class state, class action, class environment>
249 //void DynamicPotentialSearch<state,action,environment>::AddAdditionalStartState(state& newState, double cost)
250 //{
251 // fhat.AddOpenNode(newState, env->GetStateHash(newState), cost, weight*theHeuristic->HCost(start, goal));
252 // f.AddOpenNode(newState, env->GetStateHash(newState), cost, theHeuristic->HCost(start, goal));
253 //}
254 
265 template <class state, class action, class environment>
267 {
268 
269  double fmin = DBL_MAX;
270  // get best f on open
271  for (const auto &item : openClosed)
272  {
273  auto &i = item.second;
274  if (i.open == true && fless(i.g+i.h, fmin))
275  fmin = i.g+i.h;
276  }
277 
278  // get best priority
279  double bestP = 0;
280  DPSData<state> *next = 0;
281  for (auto &item : openClosed)
282  {
283  auto &i = item.second;
284  // // (B × fmin − g(n))/h(n)
285  if (i.open)
286  {
287  double pr = DBL_MAX;
288  if (i.h != 0)
289  pr = (bound * fmin - i.g)/i.h;
290  if (fgreater(pr, bestP))
291  {
292  bestP = pr;
293  next = &i;
294  }
295  }
296  }
297  if (next == 0)
298  {
299  // no path found
300  return true;
301  }
302 // std::cout << "Expanding " << next->data << " with priority " << bestP << "\n";
303  next->open = false;
304 
305  nodesExpanded++;
306  if (env->GoalTest(next->data, goal))
307  {
308  ExtractPathToStart(next->data, thePath);
309  return true;
310  }
311 
312  env->GetSuccessors(next->data, neighbors);
313 
314  // iterate again updating costs and writing out to memory
315  for (int x = 0; x < neighbors.size(); x++)
316  {
317  uint64_t hash = env->GetStateHash(neighbors[x]);
318  double edgeCost = env->GCost(next->data, neighbors[x]);
319  nodesTouched++;
320 
321  auto item = openClosed.find(hash);
322 
323  if (item == openClosed.end()) // not found
324  {
325  openClosed[hash] = {neighbors[x], next->g+edgeCost, theHeuristic->HCost(neighbors[x], goal), next->data};
326  continue;
327  }
328  auto &i = item->second;
329  if (fless(next->g+edgeCost+i.h, i.g+i.h)) // found shorter path
330  {
331  i.parent = next->data;
332  i.g = next->g+edgeCost;
333  if (i.open == false)
334  {
335  i.open = true;
336  i.reopened = true;
337  }
338  }
339  }
340  return false;
341 }
342 
343 template <class state, class action, class environment>
345 {
346  double fmin = DBL_MAX;
347  // get best f on open
348  for (const auto &item : openClosed)
349  {
350  auto &i = item.second;
351  if (i.open == true && fless(i.g+i.h, fmin))
352  fmin = i.g+i.h;
353  }
354  //std::cout << "-->Best fmnin " << fmin << "\n";
355  return fmin;
356 }
357 
358 template <class state, class action, class environment>
360 {
361  iter = openClosed.begin();
362  while ((iter != openClosed.end()) && iter->second.open == false)
363  {
364  iter++;
365  }
366 }
367 
368 template <class state, class action, class environment>
370 {
371  if (iter == openClosed.end())
372  return false;
373  g = iter->second.g;
374  h = iter->second.h;
375  //std::cout << " " << iter->second.data;
376  iter++;
377  while ((iter != openClosed.end()) && iter->second.open == false)
378  {
379  iter++;
380  }
381  return true;
382 }
383 
385 // * Returns the next state on the open list (but doesn't pop it off the queue).
386 // * @author Nathan Sturtevant
387 // * @date 03/22/06
388 // *
389 // * @return The first state in the open list.
390 // */
391 //template <class state, class action, class environment>
392 //state DynamicPotentialSearch<state, action,environment>::CheckNextNode()
393 //{
394 // uint64_t key = fhat.Peek();
395 // return fhat.Lookup(key).data;
396 // //assert(false);
397 // //return openQueue.top().currNode;
398 //}
399 
400 
402 // * Get the path from a goal state to the start state
403 // * @author Nathan Sturtevant
404 // * @date 03/22/06
405 // *
406 // * @param goalNode the goal state
407 // * @param thePath will contain the path from goalNode to the start state
408 // */
409 //template <class state, class action,class environment,class openList>
410 //void DynamicPotentialSearch<state, action,environment>::ExtractPathToStartFromID(uint64_t node,
411 // std::vector<state> &thePath)
412 //{
413 // do {
414 // thePath.push_back(fhat.Lookup(node).data);
415 // node = fhat.Lookup(node).parentID;
416 // } while (fhat.Lookup(node).parentID != node);
417 // thePath.push_back(fhat.Lookup(node).data);
418 //}
419 
420 //template <class state, class action,class environment,class openList>
421 //const state &DynamicPotentialSearch<state, action,environment>::GetParent(const state &s)
422 //{
423 // uint64_t theID;
424 // fhat.Lookup(env->GetStateHash(s), theID);
425 // theID = fhat.Lookup(theID).parentID;
426 // return fhat.Lookup(theID).data;
427 //}
428 
430 // * A function that prints the number of states in the closed list and open
431 // * queue.
432 // * @author Nathan Sturtevant
433 // * @date 03/22/06
434 // */
435 //template <class state, class action, class environment>
436 //void DynamicPotentialSearch<state, action,environment>::PrintStats()
437 //{
438 // printf("%u items in closed list\n", (unsigned int)fhat.ClosedSize());
439 // printf("%u items in open queue\n", (unsigned int)fhat.OpenSize());
440 //}
441 //
443 // * Return the amount of memory used by DynamicPotentialSearch
444 // * @author Nathan Sturtevant
445 // * @date 03/22/06
446 // *
447 // * @return The combined number of elements in the closed list and open queue
448 // */
449 //template <class state, class action, class environment>
450 //int DynamicPotentialSearch<state, action,environment>::GetMemoryUsage()
451 //{
452 // return fhat.size();
453 //}
454 
456 // * Get state from the closed list
457 // * @author Nathan Sturtevant
458 // * @date 10/09/07
459 // *
460 // * @param val The state to lookup in the closed list
461 // * @gCost The g-cost of the node in the closed list
462 // * @return success Whether we found the value or not
463 // * the states
464 // */
465 //template <class state, class action, class environment>
466 //bool DynamicPotentialSearch<state, action,environment>::GetClosedListGCost(const state &val, double &gCost) const
467 //{
468 // uint64_t theID;
469 // dataLocation loc = fhat.Lookup(env->GetStateHash(val), theID);
470 // if (loc == kClosedList)
471 // {
472 // gCost = fhat.Lookat(theID).g;
473 // return true;
474 // }
475 // return false;
476 //}
477 
478 //template <class state, class action, class environment>
479 //bool DynamicPotentialSearch<state, action,environment>::GetOpenListGCost(const state &val, double &gCost) const
480 //{
481 // uint64_t theID;
482 // dataLocation loc = fhat.Lookup(env->GetStateHash(val), theID);
483 // if (loc == kOpenList)
484 // {
485 // gCost = fhat.Lookat(theID).g;
486 // return true;
487 // }
488 // return false;
489 //}
490 
491 //template <class state, class action, class environment>
492 //bool DynamicPotentialSearch<state, action,environment>::GetClosedItem(const state &s, AStarOpenClosedData<state> &result)
493 //{
494 // uint64_t theID;
495 // dataLocation loc = fhat.Lookup(env->GetStateHash(s), theID);
496 // if (loc == kClosedList)
497 // {
498 // result = fhat.Lookat(theID);
499 // return true;
500 // }
501 // return false;
502 //
503 //}
504 
505 
512 template <class state, class action, class environment>
514 {
515 
516 }
517 
518 template <class state, class action, class environment>
520 {
521  double transparency = 1.0;
522 
523  for (const auto &item : openClosed)
524  {
525  const auto &i = item.second;
526  if (i.open && i.reopened)
527  {
528  env->SetColor(0.0, 0.5, 0.5, transparency);
529  env->Draw(d, i.data);
530  }
531  else if (i.open)
532  {
533  env->SetColor(0.0, 1.0, 0.0, transparency);
534  env->Draw(d, i.data);
535  }
536  else if (!i.open && i.reopened)
537  {
538  env->SetColor(0.5, 0.0, 0.5, transparency);
539  env->Draw(d, i.data);
540  }
541  else if (!i.open)
542  {
543  env->SetColor(1.0, 0.0, 0.0, transparency);
544  env->Draw(d, i.data);
545  }
546  }
547  env->SetColor(1.0, 0.5, 1.0, 0.5);
548  env->Draw(d, goal);
549 }
550 
551 #endif /* DynamicPotentialSearch_h */
GenericSearchAlgorithm.h
An interface for generic search algorithms.
BucketOpenClosed.h
DynamicPotentialSearch
Definition: DynamicPotentialSearch.h:56
DynamicPotentialSearch::nodesTouched
uint64_t nodesTouched
Definition: DynamicPotentialSearch.h:123
DynamicPotentialSearch::GetOptimalityBound
double GetOptimalityBound()
Definition: DynamicPotentialSearch.h:121
DynamicPotentialSearch::uniqueNodesExpanded
uint64_t uniqueNodesExpanded
Definition: DynamicPotentialSearch.h:134
DPSData::DPSData
DPSData(const state &theData, double gCost, double hCost, const state &par)
Definition: DynamicPotentialSearch.h:43
Heuristic
Definition: Heuristic.h:30
if
if(state==GLUT_DOWN)
Definition: GLUThog.cpp:244
AStarOpenClosed.h
d
mcData d[]
Definition: MotionCaptureMovement.cpp:21
DPSData::reopened
bool reopened
Definition: DynamicPotentialSearch.h:50
DynamicPotentialSearch::PrintStats
void PrintStats()
DynamicPotentialSearch::theHeuristic
Heuristic< state > * theHeuristic
Definition: DynamicPotentialSearch.h:135
DynamicPotentialSearch::weight
double weight
Definition: DynamicPotentialSearch.h:131
FPUtil.h
DPSData::h
double h
Definition: DynamicPotentialSearch.h:47
DynamicPotentialSearch::nodesExpanded
uint64_t nodesExpanded
Definition: DynamicPotentialSearch.h:123
DynamicPotentialSearch::ResetNodeCount
void ResetNodeCount()
Definition: DynamicPotentialSearch.h:87
DynamicPotentialSearch::GetParent
const state & GetParent(const state &s)
DynamicPotentialSearch::~DynamicPotentialSearch
virtual ~DynamicPotentialSearch()
Definition: DynamicPotentialSearch.h:59
DynamicPotentialSearch::GetReopenNodes
bool GetReopenNodes()
Definition: DynamicPotentialSearch.h:107
DynamicPotentialSearch::OpenGLDraw
void OpenGLDraw() const
‍**
Definition: DynamicPotentialSearch.h:513
DynamicPotentialSearch::neighbors
std::vector< state > neighbors
Definition: DynamicPotentialSearch.h:125
DynamicPotentialSearch::DoSingleSearchStep
bool DoSingleSearchStep(std::vector< state > &thePath)
‍**
Definition: DynamicPotentialSearch.h:266
DPSData
A templated version of A*, based on HOG genericAStar.
Definition: DynamicPotentialSearch.h:40
DynamicPotentialSearch::SetOptimalityBound
void SetOptimalityBound(double w)
Definition: DynamicPotentialSearch.h:120
DynamicPotentialSearch::goal
state goal
Definition: DynamicPotentialSearch.h:66
DynamicPotentialSearch::Draw
void Draw(Graphics::Display &d) const
Definition: DynamicPotentialSearch.h:519
Graphics::Display
Definition: Graphics.h:146
fless
bool fless(double a, double b)
Definition: FPUtil.h:28
DPSData::g
double g
Definition: DynamicPotentialSearch.h:46
DPSData::data
state data
Definition: DynamicPotentialSearch.h:45
TemplateAStar.h
DynamicPotentialSearch::ExtractPathToStart
void ExtractPathToStart(const state &node, std::vector< state > &thePath)
Definition: DynamicPotentialSearch.h:74
DynamicPotentialSearch::GetNodesExpanded
uint64_t GetNodesExpanded() const
Definition: DynamicPotentialSearch.h:111
DPSData::open
bool open
Definition: DynamicPotentialSearch.h:49
fgreater
bool fgreater(double a, double b)
Definition: FPUtil.h:29
DPSData::parent
state parent
Definition: DynamicPotentialSearch.h:48
DynamicPotentialSearch::GetPath
void GetPath(environment *env, const state &from, const state &to, std::vector< state > &thePath)
Perform an A* search between two states.
Definition: DynamicPotentialSearch.h:169
DynamicPotentialSearch::start
state start
Definition: DynamicPotentialSearch.h:66
DynamicPotentialSearch::env
environment * env
Definition: DynamicPotentialSearch.h:129
DynamicPotentialSearch::SetHeuristic
void SetHeuristic(Heuristic< state > *h)
Definition: DynamicPotentialSearch.h:109
DPSData::DPSData
DPSData()
Definition: DynamicPotentialSearch.h:42
DynamicPotentialSearch::GetMemoryUsage
int GetMemoryUsage()
DynamicPotentialSearch::openClosed
std::unordered_map< uint64_t, DPSData< state > > openClosed
Definition: DynamicPotentialSearch.h:64
DynamicPotentialSearch::InitializeSearch
bool InitializeSearch(environment *env, const state &from, const state &to, std::vector< state > &thePath)
Initialize the A* search.
Definition: DynamicPotentialSearch.h:209
DynamicPotentialSearch::reopenNodes
bool reopenNodes
Definition: DynamicPotentialSearch.h:133
DynamicPotentialSearch::GetName
virtual const char * GetName()
Return the name of the algorithm.
Definition: DynamicPotentialSearch.h:150
DynamicPotentialSearch::iter
std::unordered_map< uint64_t, DPSData< state > >::const_iterator iter
Definition: DynamicPotentialSearch.h:65
path
A linked list of nodes which form a continuous path.
Definition: Path.h:20
DynamicPotentialSearch::ResetIterator
void ResetIterator()
Definition: DynamicPotentialSearch.h:359
DynamicPotentialSearch::bound
double bound
Definition: DynamicPotentialSearch.h:132
DynamicPotentialSearch::GetNodesTouched
uint64_t GetNodesTouched() const
Definition: DynamicPotentialSearch.h:112
DynamicPotentialSearch::GetNext
bool GetNext(double &g, double &h)
Definition: DynamicPotentialSearch.h:369
DynamicPotentialSearch::SetReopenNodes
void SetReopenNodes(bool re)
Definition: DynamicPotentialSearch.h:106
DynamicPotentialSearch::DynamicPotentialSearch
DynamicPotentialSearch()
Definition: DynamicPotentialSearch.h:58
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
DynamicPotentialSearch::GetBestFMin
double GetBestFMin()
Definition: DynamicPotentialSearch.h:344
DynamicPotentialSearch::bestSolution
double bestSolution
Definition: DynamicPotentialSearch.h:130