HOG2
Focal.h
Go to the documentation of this file.
1 //
2 // Focal.h
3 // HOG2 Demos
4 //
5 // Created by Nathan Sturtevant on 1/8/20.
6 //
7 
8 #ifndef Focal_h
9 #define Focal_h
10 
11 
12 #include <iostream>
13 #include "FPUtil.h"
14 #include <unordered_map>
15 #include "AStarOpenClosed.h"
16 #include "BucketOpenClosed.h"
17 #include "TemplateAStar.h"
18 //#include "SearchEnvironment.h" // for the SearchEnvironment class
19 #include "float.h"
20 #include <algorithm> // for vector reverse
21 #include "GenericSearchAlgorithm.h"
22 #include <functional>
23 
24 // bool operator()(const AStarOpenClosedData<state> &i1, const AStarOpenClosedData<state> &i2) const
25 // {
26 // if (fequal(i1.h, i2.h))
27 // {
28 // return (fless(i1.g, i2.g));
29 // }
30 // return (fgreater(i1.h, i2.h));
31 // }
32 //};
33 
34 
43 template <class state, class action, class environment>
44 class Focal : public GenericSearchAlgorithm<state,action,environment> {
45 public:
46  Focal(double optimalBound = 2)
47  {
48  ResetNodeCount(); env = 0; bound = optimalBound; theHeuristic = 0;
49  phi_open = ([=](double h, double g){return g+h;});
50  phi_focal = ([=](double h, double g){return g+(2*bound-1)*h;});
51  }
52  virtual ~Focal() {}
53  void GetPath(environment *env, const state& from, const state& to, std::vector<state> &thePath);
54  void GetPath(environment *, const state& , const state& , std::vector<action> & );
55 
56  // uses admissible heuristic (regular A* search)
57  //AStarOpenClosed<state, AStarCompare<state>> f;
58  // uses inadmissible heuristic
59  //AStarOpenClosed<state, GBFSCompare<state>> focal;
60  state goal, start;
61 
62  bool InitializeSearch(environment *env, const state& from, const state& to, std::vector<state> &thePath);
63  bool DoSingleSearchStep(std::vector<state> &thePath);
64 
65  void ExtractPathToStart(state &node, std::vector<state> &thePath)
66  { uint64_t theID; focal.Lookup(env->GetStateHash(node), theID); ExtractPathToStartFromID(theID, thePath); }
67  void ExtractPathToStartFromID(size_t node, std::vector<state> &thePath);
68  const state &GetParent(const state &s);
69  virtual const char *GetName();
70 
71  void PrintStats();
74  int GetMemoryUsage();
75 
76  state CheckNextOpenNode();
77  state CheckNextFocalNode();
78  bool GetOpenListGCost(const state &val, double &gCost) const;
79  bool GetFocalListGCost(const state &val, double &gCost) const;
80 
81 // bool GetClosedListGCost(const state &val, double &gCost) const;
82 // bool GetClosedItem(const state &s, AStarOpenClosedData<state> &);
83  //{ return focal.Lookat(focal.GetOpenItem(which)); }
84  inline const int GetNumItems() { return states.size(); }
85 // inline const AStarOpenClosedData<state> &GetItem(unsigned int which) { return states[which]; }
86 // bool HaveExpandedState(const state &val)
87 // { uint64_t key; return focal.Lookup(env->GetStateHash(val), key) != kNotFound; }
88 // dataLocation GetStateLocation(const state &val)
89 // { uint64_t key; return focal.Lookup(env->GetStateHash(val), key); }
90 
92 
93  uint64_t GetNodesExpanded() const { return nodesExpanded; }
94  uint64_t GetNodesTouched() const { return nodesTouched; }
95 
97 
98  void OpenGLDraw() const;
99  void Draw(Graphics::Display &d) const;
100 
101  void SetOptimalityBound(double w) {bound = w; phi_focal = ([=](double h, double g){return g+(2*bound-1)*h;});}
102  double GetOptimalityBound() { return bound; }
103  enum stateLoc {
107  };
108  struct SearchState {
109  double f_open;
110  double f_focal;
111  double g, h;
112  state s;
113  stateLoc where; // which data structures
114  size_t parent; // location in states
115  bool reopened;
116  };
117 
118  unsigned int GetNumOpenItems() { return open.Size(); }
119  unsigned int GetNumFocalItems() { return focal.Size(); }
121  {
122  return states[open.GetNode(which).location];
123  }
124  //{ return f.Lookat(f.GetOpenItem(which)); }
126  {
127  return states[focal.GetNode(which).location];
128  }
129 private:
130  struct OpenTreapItem {
131  size_t location;
132  std::vector<SearchState> *dataVector;
133  bool operator<(const OpenTreapItem &i)
134  {
135  auto &me = (*dataVector)[location];
136  auto &other = (*(i.dataVector))[i.location];
137 
138  if (fequal(me.f_open, other.f_open))
139  {
140  if (fequal(me.h, other.h))
141  return me.s<other.s;
142  return fless(me.h, other.h);
143  }
144  return fless(me.f_open, other.f_open);
145  }
146  bool operator==(const OpenTreapItem &i) const
147  {
148  return location==i.location;
149  }
150  bool operator>(double i)
151  {
152  auto &me = (*dataVector)[location];
153  return fgreatereq(me.f_open, i);
154  }
155  bool operator<=(double i)
156  {
157  auto &me = (*dataVector)[location];
158  return flesseq(me.f_open, i);
159  }
160 
161  friend std::ostream& operator<<(std::ostream& o, OpenTreapItem const& obj )
162  {
163  o << obj.dataVector->at(obj.location).s;
164  return o;
165  }
166  };
167  struct FocalTreapItem {
168  size_t location;
169  std::vector<SearchState> *dataVector;
171  {
172  auto &me = (*dataVector)[location];
173  auto &other = (*(i.dataVector))[i.location];
174 
175  if (fequal(me.f_focal, other.f_focal))
176  {
177  if (fequal(me.h, other.h))
178  return me.s<other.s;
179  return fless(me.h, other.h);
180  }
181  return fless(me.f_focal, other.f_focal);
182  }
183  bool operator==(const FocalTreapItem &i) const
184  {
185  return location==i.location;
186  }
187  friend std::ostream& operator<<(std::ostream& o, FocalTreapItem const& obj )
188  {
189  o << obj.dataVector->at(obj.location).s;
190  return o;
191  }
192  };
194  {
195  auto i = open.Peek();
196  return (*i.dataVector)[i.location];
197  }
199  {
200  auto i = focal.Peek();
201  return (*i.dataVector)[i.location];
202  }
203  void Add(state &s, double g, double h, size_t parent);
206  std::unordered_map<state, size_t> hash; // map from state to index in states vector
207  std::vector<SearchState> states;
208  std::function<double(double, double)> phi_focal;
209  std::function<double(double, double)> phi_open;
210 
211  void DrawOpen(Graphics::Display &d) const;
212  void DrawFocal(Graphics::Display &d) const;
213  void ExpandOpen();
214  void ExpandFocal();
216 
217  std::vector<state> neighbors;
218  std::vector<uint64_t> neighborID;
219  std::vector<double> edgeCosts;
220  std::vector<dataLocation> neighborLoc;
221 
222  std::vector<state> solution;
223  environment *env;
224  double bestSolution;
225  double bound;
227  double minF;
229 };
230 
231 //static const bool verbose = false;
232 
241 template <class state, class action, class environment>
243 {
244  static char name[32];
245  sprintf(name, "Focal[%1.2f]", bound);
246  return name;
247 }
248 
260 template <class state, class action, class environment>
261 void Focal<state,action,environment>::GetPath(environment *_env, const state& from, const state& to, std::vector<state> &thePath)
262 {
263  //discardcount=0;
264  if (!InitializeSearch(_env, from, to, thePath))
265  {
266  return;
267  }
268  while (!DoSingleSearchStep(thePath))
269  {
270  // if (0 == nodesExpanded%100000)
271  // printf("%" PRId64 " nodes expanded\n", nodesExpanded);
272  }
273 }
274 
275 template <class state, class action, class environment>
276 void Focal<state,action,environment>::GetPath(environment *_env, const state& from, const state& to, std::vector<action> &path)
277 {
278  std::vector<state> thePath;
279  if (!InitializeSearch(_env, from, to, thePath))
280  {
281  return;
282  }
283  path.resize(0);
284  while (!DoSingleSearchStep(thePath))
285  {
286  }
287  for (int x = 0; x < thePath.size()-1; x++)
288  {
289  path.push_back(_env->GetAction(thePath[x], thePath[x+1]));
290  }
291 }
292 
293 
304 template <class state, class action, class environment>
305 bool Focal<state,action,environment>::InitializeSearch(environment *_env, const state& from, const state& to, std::vector<state> &thePath)
306 {
307  bestSolution = DBL_MAX;
308 
309  if (theHeuristic == 0)
310  theHeuristic = _env;
311  thePath.resize(0);
312  env = _env;
313  focal.Reset();
314  open.Reset();
315  solution.clear();
316  ResetNodeCount();
317  hash.clear();
318  start = from;
319  goal = to;
320  minF = 0;
321 
322  if (env->GoalTest(from, to)) //assumes that from and to are valid states
323  {
324  return false;
325  }
326 
327  states.resize(0);
328  Add(start, 0, theHeuristic->HCost(start, goal), states.size()); // should be 0
329 // focal.AddOpenNode(start, env->GetStateHash(start), 0, theHeuristic->HCost(start, goal));
330 // f.AddOpenNode(start, env->GetStateHash(start), 0, theHeuristic->HCost(start, goal));
331  return true;
332 }
333 
335 // * Add additional start state to the search. This should only be called after Initialize Search and before DoSingleSearchStep.
336 // * @author Nathan Sturtevant
337 // * @date 01/06/08
338 // */
339 //template <class state, class action, class environment>
340 //void Focal<state,action,environment>::AddAdditionalStartState(state& newState)
341 //{
342 // focal.AddOpenNode(newState, env->GetStateHash(newState), 0, weight*theHeuristic->HCost(start, goal));
343 // f.AddOpenNode(newState, env->GetStateHash(newState), 0, theHeuristic->HCost(start, goal));
344 //}
345 //
347 // * Add additional start state to the search. This should only be called after Initialize Search
348 // * @author Nathan Sturtevant
349 // * @date 09/25/10
350 // */
351 //template <class state, class action, class environment>
352 //void Focal<state,action,environment>::AddAdditionalStartState(state& newState, double cost)
353 //{
354 // focal.AddOpenNode(newState, env->GetStateHash(newState), cost, weight*theHeuristic->HCost(start, goal));
355 // f.AddOpenNode(newState, env->GetStateHash(newState), cost, theHeuristic->HCost(start, goal));
356 //}
357 
368 template <class state, class action, class environment>
370 {
371  if (solution.size() > 0)
372  {
373  thePath = solution;
374  return true;
375  }
376  if (open.Size() == 0)
377  {
378  printf("No path\n");
379  thePath.resize(0); // no path found!
380  return true;
381  }
382 
383  uint64_t nodeOnfocal;
384  uint64_t nodeOnF;
385  // only reopen states taken from f, not fhat
386  bool reopen = true;
387 
388  size_t bestOpenLoc = open.Peek().location;
389  double regularF = states[bestOpenLoc].f_open; //f.Lookat(f.Peek()).g+f.Lookat(f.Peek()).h;
390  if (fless(minF, regularF)) // minimum cost increased!
391  {
392  std::function<void (const OpenTreapItem &)> func = [&](const OpenTreapItem &i)
393  { // Move item to focal
394  FocalTreapItem f = {i.location, i.dataVector};
395  if (states[i.location].where == kOpenList)
396  {
397 // std::cout << "-->Moving " << states[i.location].s << "(f:" << states[i.location].f_open << ") to focal.\n";
398  focal.Add(f);
399  states[i.location].where = kOpenFocalList;
400  }
401  };
402  // Add all states in the bound to focal
403  open.Iterate(minF*bound, regularF*bound, func);
404  minF = regularF;
405  }
406 
407  if (focal.Size() > 0)
408  {
409  size_t bestFocalLoc = focal.Peek().location;
410  double focalF = states[bestFocalLoc].f_focal;//focal.Lookat(focal.Peek()).g+focal.Lookat(focal.Peek()).h;
411  if (flesseq(states[bestFocalLoc].f_open, bound*regularF))
412  {
413 // printf(" Expanding focal\n");
414  ExpandFocal();
415  }
416  else {
417 // printf("Min f: %1.2f; next focal f: %1.2f. Max allowable: %1.2f.\n", regularF, states[bestFocalLoc].f_open, regularF*bound);
418  printf("ERROR: Expanding open\n");
419  ExpandOpen();
420  }
421  }
422  else {
423 // printf("-->Expanding open\n");
424  ExpandOpen();
425  }
426 
427  if (solution.size() > 0)
428  {
429  thePath = solution;
430  return true;
431  }
432 
433 // if (fless(focal.Lookat(focal.Peek()).g+focal.Lookat(focal.Peek()).h, bestSolution))
434 // {
435 // nodeOnfocal = focal.Close();
436 // reopen = false;
437 // dataLocation d = f.Lookup(env->GetStateHash(focal.Lookup(nodeOnfocal).data), nodeOnF);
438 // assert(d != kNotFound);
440 // }
441 // else {
442 // nodeOnF = f.Close();
443 // reopen = true;
444 // dataLocation d = focal.Lookup(env->GetStateHash(f.Lookup(nodeOnF).data), nodeOnfocal);
445 // assert(d != kNotFound);
446 // if (d == kOpenList)
447 // {
448 // focal.Close(nodeOnfocal);
449 // d = focal.Lookup(env->GetStateHash(f.Lookup(nodeOnF).data), nodeOnfocal);
450 // assert(d == kClosedList);
451 // }
452 // }
453 //
454 // if (!fequal(oldF, f.Lookat(f.Peek()).g+f.Lookat(f.Peek()).h))
455 // {
456 // printf("Best solution %1.2f\n", bestSolution);
457 // printf("Best on open %1.2f - lower bound is %1.2f\n", f.Lookat(f.Peek()).g+f.Lookat(f.Peek()).h,
458 // (f.Lookat(f.Peek()).g+f.Lookat(f.Peek()).h)*bound);
459 // }
460 // if (!focal.Lookup(nodeOnfocal).reopened)
461 // uniqueNodesExpanded++;
462 // nodesExpanded++;
463 //
464 // // if n is a goal then
465 // // incumbent ← n
466 // if (env->GoalTest(focal.Lookup(nodeOnfocal).data, goal))
467 // {
468 // // Actually extract the path, since the cost may not actually be the g-cost
469 // ExtractPathToStartFromID(nodeOnfocal, thePath);
470 // bestSolution = env->GetPathLength(thePath);
471 // thePath.resize(0);
472 // printf("Best solution %1.2f\n", bestSolution);
473 // printf("Best on open %1.2f - lower bound is %1.2f\n", f.Lookat(f.Peek()).g+f.Lookat(f.Peek()).h,
474 // (f.Lookat(f.Peek()).g+f.Lookat(f.Peek()).h)*bound);
475 //
476 // return false; // check on next iteration through the loop
477 // }
478 
479 
480  // std::cout << "Expanding: " << focal.Lookup(nodeOnfocal).data << " with f:";
481  // std::cout << focal.Lookup(nodeid).g+focal.Lookup(nodeOnfocal).h << std::endl;
482 
483  return false;
484 }
485 
491 template <class state, class action, class environment>
493 {
494  auto i = open.RemoveSmallest();
495 // std::cout << states[i.location].s << " expanded from open\n";
496  if (!states[i.location].reopened)
497  uniqueNodesExpanded++;
498  nodesExpanded++;
499  states[i.location].where = kClosedList;
500 
501  if (env->GoalTest(states[i.location].s, goal))
502  {
503  ExtractPathToStartFromID(i.location, solution);
504  // Path is backwards - reverse
505  reverse(solution.begin(), solution.end());
506  return;
507  }
508 
509  neighbors.resize(0);
510  env->GetSuccessors(states[i.location].s, neighbors);
511  for (unsigned int x = 0; x < neighbors.size(); x++)
512  Add(neighbors[x], states[i.location].g+env->GCost(states[i.location].s, neighbors[x]),
513  env->HCost(neighbors[x], goal), i.location);
514 
515 // // env->GetSuccessors(f.Lookup(nodeid).data, neighbors);
516 // // 1. load all the children
517 // for (unsigned int x = 0; x < neighbors.size(); x++)
518 // {
519 // uint64_t theID;
520 // neighborLoc.push_back(f.Lookup(env->GetStateHash(neighbors[x]), theID));
521 // neighborID.push_back(theID);
522 // edgeCosts.push_back(env->GCost(f.Lookup(nodeid).data, neighbors[x]));
523 // }
524 //
525 // // iterate again updating costs and writing out to memory
526 // for (int x = 0; x < neighbors.size(); x++)
527 // {
528 // nodesTouched++;
529 //
530 // switch (neighborLoc[x])
531 // {
532 // case kClosedList:
546 // break;
547 // case kOpenList:
548 // //edgeCost = env->GCost(f.Lookup(nodeid).data, neighbors[x]);
549 // if (fless(f.Lookup(nodeid).g+edgeCosts[x], f.Lookup(neighborID[x]).g))
550 // {
551 // f.Lookup(neighborID[x]).parentID = nodeid;
552 // f.Lookup(neighborID[x]).g = f.Lookup(nodeid).g+edgeCosts[x];
553 // // This line isn't normally needed, but in some state spaces we might have
554 // // equality but different meta information, so we need to make sure that the
555 // // meta information is also copied, since this is the most generic A* implementation
556 // f.Lookup(neighborID[x]).data = neighbors[x];
557 // f.KeyChanged(neighborID[x]);
558 // // std::cout << " Reducing cost to " << f.Lookup(nodeid).g+edgeCosts[x] << "\n";
559 // // TODO: unify the KeyChanged calls.
560 // }
561 // else {
562 // // std::cout << " no cheaper \n";
563 // }
564 // break;
565 // case kNotFound:
566 // {
567 // f.AddOpenNode(neighbors[x],
568 // env->GetStateHash(neighbors[x]),
569 // f.Lookup(nodeid).g+edgeCosts[x],
570 // theHeuristic->HCost(neighbors[x], goal),
571 // nodeid);
572 // }
573 // }
574 // }
575 }
576 
577 template <class state, class action, class environment>
579 {
580  auto i = focal.RemoveSmallest();
581 // std::cout << states[i.location].s << " expanded from focal\n";
582  if (!states[i.location].reopened)
583  uniqueNodesExpanded++;
584  nodesExpanded++;
585 
586  states[i.location].where = kOpenList;
587 
588  if (env->GoalTest(states[i.location].s, goal))
589  {
590  ExtractPathToStartFromID(i.location, solution);
591  // Path is backwards - reverse
592  reverse(solution.begin(), solution.end());
593  return;
594  }
595 
596  neighbors.resize(0);
597  env->GetSuccessors(states[i.location].s, neighbors);
598  for (unsigned int x = 0; x < neighbors.size(); x++)
599  Add(neighbors[x], states[i.location].g+env->GCost(states[i.location].s, neighbors[x]),
600  env->HCost(neighbors[x], goal), i.location);
601 //
602 //
603 // uint64_t nodeid = focal.Close();
604 // if (!focal.Lookup(nodeid).reopened)
605 // uniqueNodesExpanded++;
606 // nodesExpanded++;
607 //
608 // if (env->GoalTest(focal.Lookup(nodeid).data, goal))
609 // {
610 // ExtractPathToStartFromID(nodeid, solution);
611 // // Path is backwards - reverse
612 // reverse(solution.begin(), solution.end());
613 // return;
614 // }
615 //
616 // neighbors.resize(0);
617 // edgeCosts.resize(0);
618 // neighborID.resize(0);
619 // neighborLoc.resize(0);
620 //
621 // std::cout << "Expanding: " << focal.Lookup(nodeid).data << " with f:";
622 // std::cout << focal.Lookup(nodeid).g+focal.Lookup(nodeid).h << std::endl;
623 //
624 // env->GetSuccessors(focal.Lookup(nodeid).data, neighbors);
625 // double bestH = focal.Lookup(nodeid).h;
626 // double lowHC = DBL_MAX;
627 // // 1. load all the children
628 // for (unsigned int x = 0; x < neighbors.size(); x++)
629 // {
630 // uint64_t theID;
631 // neighborLoc.push_back(focal.Lookup(env->GetStateHash(neighbors[x]), theID));
632 // neighborID.push_back(theID);
633 // edgeCosts.push_back(env->GCost(focal.Lookup(nodeid).data, neighbors[x]));
634 // }
635 //
636 // // iterate again updating costs and writing out to memory
637 // for (int x = 0; x < neighbors.size(); x++)
638 // {
639 // nodesTouched++;
640 //
641 // switch (neighborLoc[x])
642 // {
643 // case kClosedList:
644 // break;
645 // case kOpenList:
646 // //edgeCost = env->GCost(focal.Lookup(nodeid).data, neighbors[x]);
647 // if (fless(focal.Lookup(nodeid).g+edgeCosts[x], focal.Lookup(neighborID[x]).g))
648 // {
649 // focal.Lookup(neighborID[x]).parentID = nodeid;
650 // focal.Lookup(neighborID[x]).g = focal.Lookup(nodeid).g+edgeCosts[x];
651 // // This line isn't normally needed, but in some state spaces we might have
652 // // equality but different meta information, so we need to make sure that the
653 // // meta information is also copied, since this is the most generic A* implementation
654 // focal.Lookup(neighborID[x]).data = neighbors[x];
655 // focal.KeyChanged(neighborID[x]);
656 // // std::cout << " Reducing cost to " << focal.Lookup(nodeid).g+edgeCosts[x] << "\n";
657 // // TODO: unify the KeyChanged calls.
658 // }
659 // else {
660 // // std::cout << " no cheaper \n";
661 // }
662 // break;
663 // case kNotFound:
664 // {
665 // focal.AddOpenNode(neighbors[x],
666 // env->GetStateHash(neighbors[x]),
667 // focal.Lookup(nodeid).g+edgeCosts[x],
668 // theHeuristic->HCost(neighbors[x], goal),
669 // nodeid);
670 // }
671 // }
672 // }
673 }
674 
682 //template <class state, class action, class environment>
683 //state Focal<state, action,environment>::CheckNextNode()
684 //{
685 // uint64_t key = focal.Peek();
686 // return focal.Lookup(key).data;
687 // //assert(false);
688 // //return openQueue.top().currNode;
689 //}
690 
691 
700 template <class state, class action,class environment>
702  std::vector<state> &thePath)
703 {
704  do {
705  thePath.push_back(states[node].s);
706  node = states[node].parent;
707  } while (states[node].parent != node);
708  thePath.push_back(states[node].s);
709 }
710 
711 template <class state, class action,class environment>
713 {
714  assert(false);
715  return s;
716 // uint64_t theID;
717 // focal.Lookup(env->GetStateHash(s), theID);
718 // theID = focal.Lookup(theID).parentID;
719 // return focal.Lookup(theID).data;
720 }
721 
728 template <class state, class action, class environment>
730 {
731  printf("%u items in closed list\n", (unsigned int)focal.ClosedSize());
732  printf("%u items in open queue\n", (unsigned int)focal.OpenSize());
733 }
734 
742 template <class state, class action, class environment>
744 {
745  return focal.size();
746 }
747 
758 //template <class state, class action, class environment>
759 //bool Focal<state, action,environment>::GetClosedListGCost(const state &val, double &gCost) const
760 //{
761 // uint64_t theID;
762 // dataLocation loc = focal.Lookup(env->GetStateHash(val), theID);
763 // if (loc == kClosedList)
764 // {
765 // gCost = focal.Lookat(theID).g;
766 // return true;
767 // }
768 // return false;
769 //}
770 
771 template <class state, class action, class environment>
773 {
774  return states[open.Peek().location].s;
775 }
776 
777 template <class state, class action, class environment>
779 {
780  return states[focal.Peek().location].s;
781 }
782 
783 
784 template <class state, class action, class environment>
785 bool Focal<state, action,environment>::GetOpenListGCost(const state &val, double &gCost) const
786 {
787  auto i = hash.find(val);
788  if (i == hash.end())
789  return false;
790  if (states[i->second].where != kClosedList)
791  {
792  gCost = states[i->second].g;
793  return true;
794  }
795  return false;
796 }
797 
798 template <class state, class action, class environment>
799 bool Focal<state, action,environment>::GetFocalListGCost(const state &val, double &gCost) const
800 {
801  auto i = hash.find(val);
802  if (i == hash.end())
803  return false;
804  if (states[i->second].where == kOpenFocalList)
805  {
806  gCost = states[i->second].g;
807  return true;
808  }
809  return false;
810 }
811 //
812 //
813 //template <class state, class action, class environment>
814 //bool Focal<state, action,environment>::GetClosedItem(const state &s, AStarOpenClosedData<state> &result)
815 //{
816 // uint64_t theID;
817 // dataLocation loc = focal.Lookup(env->GetStateHash(s), theID);
818 // if (loc == kClosedList)
819 // {
820 // result = focal.Lookat(theID);
821 // return true;
822 // }
823 // return false;
824 //
825 //}
826 
827 template <class state, class action, class environment>
828 void Focal<state, action,environment>::Add(state &s, double g, double h, size_t parent)
829 {
830  auto i = hash.find(s);
831  if (i == hash.end())
832  {
834  if (open.Size() > 0)
835  {
836  auto item = open.Peek();
837  if (flesseq(g+h, states[item.location].f_open*bound))
838  {
839  loc = kOpenFocalList;
840  }
841  }
842  else
843  loc = kOpenFocalList;
844 
845  hash[s] = states.size();
846  states.push_back({
847  phi_open(h, g), //double f_open;
848  phi_focal(h, g), // double f_focal;
849  g, h, //double g, h;
850  s, //state s
851  loc, // location (open/closed/focal)
852  parent, //size_t parent; // location in states
853  false //reopened
854  });
855  if (loc == kOpenList || loc == kOpenFocalList)
856  {
857  OpenTreapItem openItem = {states.size()-1, &states};
858 // std::cout << "Adding " << s << " to open\n";
859  open.Add(openItem);
860  }
861  if (loc == kOpenFocalList)
862  {
863  FocalTreapItem focalItem = {states.size()-1, &states};
864 // std::cout << "Adding " << s << " to focal\n";
865  focal.Add(focalItem);
866  }
867  }
868  else if (fless(g, states[i->second].g)) { // update on open/focal
869  OpenTreapItem openItem = {i->second, &states};
870  FocalTreapItem focalItem = {i->second, &states};
871  states[i->second].parent = parent;
872  switch (states[i->second].where)
873  {
874  case kOpenFocalList:
875  {
876  bool result = open.Remove(openItem);
877 // std::cout << s << " removed from open\n";
878  if (result == false)
879  {
880  open.Print();
881  assert(result == true);
882  }
883  result = focal.Remove(focalItem);
884 // std::cout << s << " removed from focal\n";
885  if (result == false)
886  {
887  focal.Print();
888  assert(result == true);
889  }
890 
891  states[i->second].g = g;
892  states[i->second].f_open = phi_open(h, g);
893  states[i->second].f_focal = phi_focal(h, g);
894  open.Add(openItem);
895 // std::cout << "Adding " << s << " to open\n";
896  focal.Add(focalItem);
897 // std::cout << "Adding " << s << " to focal\n";
898  break;
899  }
900  case kOpenList:
901  {
902  bool result = open.Remove(openItem);
903 // std::cout << s << " removed from open\n";
904  if (result == false)
905  {
906  open.Print();
907  assert(result == true);
908  }
909 
910  states[i->second].g = g;
911  states[i->second].f_open = phi_open(h, g);
912  states[i->second].f_focal = phi_focal(h, g);
913  open.Add(openItem);
914 // std::cout << "Adding " << s << " to open\n";
915  auto item = open.Peek();
916 
917  // DON'T move back to focal if it is still on open
918  if (0&&flesseq(g+h, states[item.location].f_open*bound))
919  {
920 // std::cout << "Adding " << s << " to focal\n";
921  focal.Add(focalItem);
922  states[i->second].where = kOpenFocalList;
923  }
924  break;
925  }
926  case kClosedList:
927  {
928  // Put back on open/focal
929  states[i->second].g = g;
930  states[i->second].f_open = phi_open(h, g);
931  states[i->second].f_focal = phi_focal(h, g);
932  states[i->second].reopened = true;
933  open.Add(openItem);
934 // std::cout << "Adding " << s << " to open\n";
935  states[i->second].where = kOpenList;
936  auto item = open.Peek();
937  if (flesseq(g+h, states[item.location].f_open*bound))
938  {
939 // std::cout << "Adding " << s << " to focal\n";
940  focal.Add(focalItem);
941  states[i->second].where = kOpenFocalList;
942  }
943  break;
944  }
945  }
946  }
947 }
948 
955 template <class state, class action, class environment>
957 {
958 }
959 
960 template <class state, class action, class environment>
962 {
963  double transparency = 1.0;
964  for (unsigned int x = 0; x < states.size(); x++)
965  {
966  const auto &data = states[x].s;
967  if ((states[x].where == kOpenList) && (states[x].reopened))
968  {
969  env->SetColor(0.0, 0.5, 0.5, transparency);
970  env->Draw(d, data);
971  }
972  else if (states[x].where == kOpenList)
973  {
974  env->SetColor(0.0, 1.0, 0.0, transparency);
975  env->Draw(d, data);
976  }
977  else if ((states[x].where == kClosedList) && (states[x].reopened))
978  {
979  env->SetColor(0.5, 0.0, 0.5, transparency);
980  env->Draw(d, data);
981  }
982  else if (states[x].where == kClosedList)
983  {
984 // if (states[x].parent == x)
985 // env->SetColor(1.0, 0.5, 0.5, transparency);
986 // else
987  env->SetColor(1.0, 0.0, 0.0, transparency);
988  env->Draw(d, data);
989  }
990  else if ((states[x].where == kOpenFocalList) && (states[x].reopened))
991  {
992  env->SetColor(0.5, 1.0, 0.5, transparency);
993  env->Draw(d, data);
994  }
995  else if (states[x].where == kOpenFocalList)
996  {
997  env->SetColor(0.0, 0.0, 1.0, transparency);
998  env->Draw(d, data);
999  }
1000  }
1001 }
1002 
1003 #endif /* Focal_h */
Focal::OpenTreapItem::operator>
bool operator>(double i)
Definition: Focal.h:150
Focal::kOpenFocalList
@ kOpenFocalList
Definition: Focal.h:106
Focal::SearchState::reopened
bool reopened
Definition: Focal.h:115
GenericSearchAlgorithm.h
An interface for generic search algorithms.
Focal::neighborID
std::vector< uint64_t > neighborID
Definition: Focal.h:218
Focal::FocalTreapItem::operator<
bool operator<(FocalTreapItem &i)
Definition: Focal.h:170
Focal::GetNodesExpanded
uint64_t GetNodesExpanded() const
Definition: Focal.h:93
BucketOpenClosed.h
Focal::SearchState::parent
size_t parent
Definition: Focal.h:114
Focal::LogFinalStats
void LogFinalStats(StatCollection *)
Definition: Focal.h:96
Focal::GetOptimalityBound
double GetOptimalityBound()
Definition: Focal.h:102
Focal::stateLoc
stateLoc
Definition: Focal.h:103
Focal::CheckNextOpenNode
state CheckNextOpenNode()
Get state from the closed list.
Definition: Focal.h:772
Focal::GetName
virtual const char * GetName()
Return the name of the algorithm.
Definition: Focal.h:242
Focal::solution
std::vector< state > solution
Definition: Focal.h:222
fgreatereq
bool fgreatereq(double a, double b)
Definition: FPUtil.h:31
Focal::GetNodesTouched
uint64_t GetNodesTouched() const
Definition: Focal.h:94
Heuristic
Definition: Heuristic.h:30
Focal::phi_open
std::function< double(double, double)> phi_open
Definition: Focal.h:209
Focal::neighbors
std::vector< state > neighbors
Definition: Focal.h:217
AStarOpenClosed.h
d
mcData d[]
Definition: MotionCaptureMovement.cpp:21
Focal::hash
std::unordered_map< state, size_t > hash
Definition: Focal.h:206
Focal::GetPath
void GetPath(environment *env, const state &from, const state &to, std::vector< state > &thePath)
Perform an A* search between two states.
Definition: Focal.h:261
Focal::OpenTreapItem::operator<
bool operator<(const OpenTreapItem &i)
Definition: Focal.h:133
Focal::SetOptimalityBound
void SetOptimalityBound(double w)
Definition: Focal.h:101
Focal::goal
state goal
Definition: Focal.h:60
Focal::SearchState::f_open
double f_open
Definition: Focal.h:109
FPUtil.h
Focal::neighborLoc
std::vector< dataLocation > neighborLoc
Definition: Focal.h:220
Focal::GetUniqueNodesExpanded
uint64_t GetUniqueNodesExpanded()
Definition: Focal.h:72
Focal::OpenTreapItem::dataVector
std::vector< SearchState > * dataVector
Definition: Focal.h:132
Focal::GetMemoryUsage
int GetMemoryUsage()
Return the amount of memory used by Focal.
Definition: Focal.h:743
Focal::PrintStats
void PrintStats()
A function that prints the number of states in the closed list and open queue.
Definition: Focal.h:729
Focal::SetHeuristic
void SetHeuristic(Heuristic< state > *h)
Definition: Focal.h:91
Focal::Focal
Focal(double optimalBound=2)
Definition: Focal.h:46
Focal::kOpenList
@ kOpenList
Definition: Focal.h:105
Focal::OpenTreapItem::operator==
bool operator==(const OpenTreapItem &i) const
Definition: Focal.h:146
Focal::OpenTreapItem::operator<=
bool operator<=(double i)
Definition: Focal.h:155
Focal::GetNumFocalItems
unsigned int GetNumFocalItems()
Definition: Focal.h:119
Focal::PeekFocal
SearchState & PeekFocal()
Definition: Focal.h:198
Focal::GetParent
const state & GetParent(const state &s)
Definition: Focal.h:712
Focal::GetOpenListGCost
bool GetOpenListGCost(const state &val, double &gCost) const
Definition: Focal.h:785
Focal::nodesTouched
uint64_t nodesTouched
Definition: Focal.h:215
Focal::OpenTreapItem::operator<<
friend std::ostream & operator<<(std::ostream &o, OpenTreapItem const &obj)
Definition: Focal.h:161
GenericSearchAlgorithm
Definition: GenericSearchAlgorithm.h:35
Focal::DoSingleSearchStep
bool DoSingleSearchStep(std::vector< state > &thePath)
‍**
Definition: Focal.h:369
loc
Definition: MapGenerators.cpp:296
Focal::FocalTreapItem::location
size_t location
Definition: Focal.h:168
Focal::OpenTreapItem::location
size_t location
Definition: Focal.h:131
Focal::Draw
void Draw(Graphics::Display &d) const
Definition: Focal.h:961
Focal::env
environment * env
Definition: Focal.h:223
Focal::DrawFocal
void DrawFocal(Graphics::Display &d) const
Focal::bestSolution
double bestSolution
Definition: Focal.h:224
Focal::SearchState::where
stateLoc where
Definition: Focal.h:113
Graphics::Display
Definition: Graphics.h:146
fless
bool fless(double a, double b)
Definition: FPUtil.h:28
Focal::bound
double bound
Definition: Focal.h:225
Focal::CheckNextFocalNode
state CheckNextFocalNode()
Definition: Focal.h:778
Focal::edgeCosts
std::vector< double > edgeCosts
Definition: Focal.h:219
Focal::SearchState::h
double h
Definition: Focal.h:111
Focal::InitializeSearch
bool InitializeSearch(environment *env, const state &from, const state &to, std::vector< state > &thePath)
Initialize the A* search.
Definition: Focal.h:305
TemplateAStar.h
Focal::phi_focal
std::function< double(double, double)> phi_focal
Definition: Focal.h:208
Focal::GetNumItems
const int GetNumItems()
Definition: Focal.h:84
Focal::open
Treap< OpenTreapItem > open
Definition: Focal.h:205
Focal::DrawOpen
void DrawOpen(Graphics::Display &d) const
Focal::ExtractPathToStart
void ExtractPathToStart(state &node, std::vector< state > &thePath)
Definition: Focal.h:65
Focal::GetFocalListGCost
bool GetFocalListGCost(const state &val, double &gCost) const
Definition: Focal.h:799
Focal::ExpandFocal
void ExpandFocal()
Definition: Focal.h:578
Focal::OpenTreapItem
Definition: Focal.h:130
Focal::SearchState::f_focal
double f_focal
Definition: Focal.h:110
Focal::FocalTreapItem::operator==
bool operator==(const FocalTreapItem &i) const
Definition: Focal.h:183
Treap
Definition: Treap.h:14
Focal::uniqueNodesExpanded
uint64_t uniqueNodesExpanded
Definition: Focal.h:226
kOpenList
@ kOpenList
Definition: AStarOpenClosed.h:28
StatCollection
The StatCollection class is for collecting stats across different parts of the simulation.
Definition: StatCollection.h:34
Focal::FocalTreapItem
Definition: Focal.h:167
Focal::OpenGLDraw
void OpenGLDraw() const
Draw the open/closed list.
Definition: Focal.h:956
Focal::ExpandOpen
void ExpandOpen()
Expands a single state from the given open list.
Definition: Focal.h:492
Focal::SearchState::g
double g
Definition: Focal.h:111
Focal::FocalTreapItem::dataVector
std::vector< SearchState > * dataVector
Definition: Focal.h:169
Focal::focal
Treap< FocalTreapItem > focal
Definition: Focal.h:204
Focal::ExtractPathToStartFromID
void ExtractPathToStartFromID(size_t node, std::vector< state > &thePath)
Returns the next state on the open list (but doesn't pop it off the queue).
Definition: Focal.h:701
Focal::FocalTreapItem::operator<<
friend std::ostream & operator<<(std::ostream &o, FocalTreapItem const &obj)
Definition: Focal.h:187
Focal::GetNumOpenItems
unsigned int GetNumOpenItems()
Definition: Focal.h:118
Focal::SearchState
Definition: Focal.h:108
Focal::states
std::vector< SearchState > states
Definition: Focal.h:207
Focal::minF
double minF
Definition: Focal.h:227
Focal::nodesExpanded
uint64_t nodesExpanded
Definition: Focal.h:215
Focal::GetOpenItem
const Focal< state, action, environment >::SearchState & GetOpenItem(unsigned int which)
Definition: Focal.h:120
path
A linked list of nodes which form a continuous path.
Definition: Path.h:20
Focal::theHeuristic
Heuristic< state > * theHeuristic
Definition: Focal.h:228
Focal::SearchState::s
state s
Definition: Focal.h:112
fequal
bool fequal(double a, double b, double tolerance=TOLERANCE)
Definition: FPUtil.h:32
Focal
A generic focal list algorithm.
Definition: Focal.h:44
Focal::ResetNodeCount
void ResetNodeCount()
Definition: Focal.h:73
Focal::Add
void Add(state &s, double g, double h, size_t parent)
Definition: Focal.h:828
flesseq
bool flesseq(double a, double b)
Definition: FPUtil.h:30
kClosedList
@ kClosedList
Definition: AStarOpenClosed.h:29
Focal::~Focal
virtual ~Focal()
Definition: Focal.h:52
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
Focal::kClosedList
@ kClosedList
Definition: Focal.h:104
Focal::PeekOpen
SearchState & PeekOpen()
Definition: Focal.h:193
Focal::start
state start
Definition: Focal.h:60
Focal::GetFocalItem
const Focal< state, action, environment >::SearchState & GetFocalItem(unsigned int which)
Definition: Focal.h:125