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