11 #ifndef TemplateAStar_H
12 #define TemplateAStar_H
14 #define __STDC_CONSTANT_MACROS
20 #define UINT32_MAX 4294967295U
27 #include <unordered_map>
43 template <
class state>
56 template <
class state>
72 template <
class state,
class action,
class environment,
class openList = AStarOpenClosed<state, AStarCompareWithF<state>, AStarOpenClosedDataWithF<state>> >
78 phi = [](
double h,
double g){
return g+h; };
81 void GetPath(environment *
env,
const state& from,
const state& to, std::vector<state> &thePath);
82 void GetPath(environment *,
const state&,
const state&, std::vector<action> & );
87 bool InitializeSearch(environment *
env,
const state& from,
const state& to, std::vector<state> &thePath);
111 bool GetHCost(
const state &val,
double &hCost)
const;
142 void FullBPMX(uint64_t nodeID,
int distance);
150 void SetPhi(std::function<
double(
double,
double)> p)
154 double Phi(
double h,
double g)
161 phi = [=](
double h,
double g){
return g+
weight*h; };
176 std::function<double(
double,
double)>
phi;
194 template <
class state,
class action,
class environment,
class openList>
197 static char name[32];
198 sprintf(name,
"TemplateAStar[]");
213 template <
class state,
class action,
class environment,
class openList>
216 if (!InitializeSearch(_env, from, to, thePath))
220 while (!DoSingleSearchStep(thePath))
227 template <
class state,
class action,
class environment,
class openList>
230 std::vector<state> thePath;
231 if (!InitializeSearch(_env, from, to, thePath))
236 while (!DoSingleSearchStep(thePath))
239 for (
size_t x = 0; x < thePath.size()-1; x++)
241 path.push_back(_env->GetAction(thePath[x], thePath[x+1]));
256 template <
class state,
class action,
class environment,
class openList>
259 if (theHeuristic == 0)
263 openClosedList.Reset(env->GetMaxHash());
268 if (env->GoalTest(from, to) && (stopAfterGoal))
273 double h = theHeuristic->HCost(start, goal);
274 openClosedList.AddOpenNode(start, env->GetStateHash(start), phi(h, 0), 0, h);
284 template <
class state,
class action,
class environment,
class openList>
287 double h = theHeuristic->HCost(newState, goal);
288 openClosedList.AddOpenNode(newState, env->GetStateHash(newState), phi(h, 0), 0, h);
296 template <
class state,
class action,
class environment,
class openList>
299 double h = theHeuristic->HCost(newState, goal);
300 openClosedList.AddOpenNode(newState, env->GetStateHash(newState), phi(h, cost), cost, h);
313 template <
class state,
class action,
class environment,
class openList>
316 if (openClosedList.OpenSize() == 0)
322 uint64_t nodeid = openClosedList.Close();
327 if (!openClosedList.Lookup(nodeid).reopened)
328 uniqueNodesExpanded++;
331 if ((stopAfterGoal) && (env->GoalTest(openClosedList.Lookup(nodeid).data, goal)))
333 ExtractPathToStartFromID(nodeid, thePath);
335 reverse(thePath.begin(), thePath.end());
336 goalFCost = openClosedList.Lookup(nodeid).f;
342 neighborID.resize(0);
343 neighborLoc.resize(0);
348 env->GetSuccessors(openClosedList.Lookup(nodeid).data, neighbors);
349 double bestH = openClosedList.Lookup(nodeid).h;
350 double lowHC = DBL_MAX;
352 for (
unsigned int x = 0; x < neighbors.size(); x++)
355 neighborLoc.push_back(openClosedList.Lookup(env->GetStateHash(neighbors[x]), theID));
356 neighborID.push_back(theID);
357 edgeCosts.push_back(env->GCost(openClosedList.Lookup(nodeid).data, neighbors[x]));
363 bestH =
std::max(bestH, openClosedList.Lookup(theID).h-edgeCosts.back());
364 lowHC =
std::min(lowHC, openClosedList.Lookup(theID).h+edgeCosts.back());
367 double tmpH = theHeuristic->HCost(neighbors[x], goal);
369 bestH =
std::max(bestH, tmpH-edgeCosts.back());
370 lowHC =
std::min(lowHC, tmpH+edgeCosts.back());
378 openClosedList.Lookup(nodeid).h =
std::max(openClosedList.Lookup(nodeid).h, bestH);
379 openClosedList.Lookup(nodeid).h =
std::max(openClosedList.Lookup(nodeid).h, lowHC);
380 openClosedList.Lookup(nodeid).f = phi(openClosedList.Lookup(nodeid).h, openClosedList.Lookup(nodeid).g);
384 for (
size_t x = 0; x < neighbors.size(); x++)
389 theConstraint->ShouldNotGenerate(start, openClosedList.Lookup(nodeid).data, neighbors[x],
390 openClosedList.Lookup(nodeid).g+edgeCosts[x], goal))
393 switch (neighborLoc[x])
398 if (
fless(openClosedList.Lookup(neighborID[x]).h, bestH-edgeCosts[x]))
400 auto &i = openClosedList.Lookup(neighborID[x]);
401 i.h = bestH-edgeCosts[x];
403 if (useBPMX > 1) FullBPMX(neighborID[x], useBPMX-1);
408 if (
fless(openClosedList.Lookup(nodeid).g+edgeCosts[x], openClosedList.Lookup(neighborID[x]).g))
410 auto &i = openClosedList.Lookup(neighborID[x]);
412 i.g = openClosedList.Lookup(nodeid).g+edgeCosts[x];
414 openClosedList.Reopen(neighborID[x]);
418 i.data = neighbors[x];
424 if (
fless(openClosedList.Lookup(nodeid).g+edgeCosts[x], openClosedList.Lookup(neighborID[x]).g))
426 auto &i = openClosedList.Lookup(neighborID[x]);
428 i.g = openClosedList.Lookup(nodeid).g+edgeCosts[x];
433 i.data = neighbors[x];
434 openClosedList.KeyChanged(neighborID[x]);
443 if (
fgreater(bestH-edgeCosts[x], openClosedList.Lookup(neighborID[x]).h))
445 auto &i = openClosedList.Lookup(neighborID[x]);
446 i.h =
std::max(i.h, bestH-edgeCosts[x]);
448 openClosedList.KeyChanged(neighborID[x]);
458 double h = theHeuristic->HCost(neighbors[x], goal);
461 h =
std::max(h, openClosedList.Lookup(nodeid).h-edgeCosts[x]);
462 openClosedList.AddOpenNode(neighbors[x],
463 env->GetStateHash(neighbors[x]),
464 phi(
std::max(h, openClosedList.Lookup(nodeid).h-edgeCosts[x]), openClosedList.Lookup(nodeid).g+edgeCosts[x]),
465 openClosedList.Lookup(nodeid).g+edgeCosts[x],
470 openClosedList.AddOpenNode(neighbors[x],
471 env->GetStateHash(neighbors[x]),
472 phi(h, openClosedList.Lookup(nodeid).g+edgeCosts[x]),
473 openClosedList.Lookup(nodeid).g+edgeCosts[x],
496 template <
class state,
class action,
class environment,
class openList>
499 uint64_t key = openClosedList.Peek();
500 return openClosedList.Lookup(key).data;
512 template <
class state,
class action,
class environment,
class openList>
519 std::vector<state> succ;
520 env->GetSuccessors(openClosedList.Lookup(nodeID).data, succ);
521 double parentH = openClosedList.Lookup(nodeID).h;
524 for (
unsigned int x = 0; x < succ.size(); x++)
527 dataLocation loc = openClosedList.Lookup(env->GetStateHash(succ[x]), theID);
528 double edgeCost = env->GCost(openClosedList.Lookup(nodeID).data, succ[x]);
529 double newHCost = parentH-edgeCost;
535 if (
fgreater(newHCost, openClosedList.Lookup(theID).h))
537 openClosedList.Lookup(theID).h = newHCost;
538 FullBPMX(theID, distance-1);
543 if (
fgreater(newHCost, openClosedList.Lookup(theID).h))
545 openClosedList.Lookup(theID).h = newHCost;
546 openClosedList.KeyChanged(theID);
563 template <
class state,
class action,
class environment,
class openList>
565 std::vector<state> &thePath)
568 thePath.push_back(openClosedList.Lookup(
node).data);
569 node = openClosedList.Lookup(
node).parentID;
570 }
while (openClosedList.Lookup(
node).parentID !=
node);
571 thePath.push_back(openClosedList.Lookup(
node).data);
574 template <
class state,
class action,
class environment,
class openList>
578 openClosedList.Lookup(env->GetStateHash(s), theID);
579 theID = openClosedList.Lookup(theID).parentID;
580 return openClosedList.Lookup(theID).data;
583 template <
class state,
class action,
class environment,
class openList>
587 for (
unsigned int x = 0; x < openClosedList.size(); x++)
589 const auto &data = openClosedList.Lookat(x);
590 if (
fless(data.g + data.h, goalFCost))
603 template <
class state,
class action,
class environment,
class openList>
606 printf(
"%u items in closed list\n", (
unsigned int)openClosedList.ClosedSize());
607 printf(
"%u items in open queue\n", (
unsigned int)openClosedList.OpenSize());
617 template <
class state,
class action,
class environment,
class openList>
620 return openClosedList.size();
633 template <
class state,
class action,
class environment,
class openList>
637 dataLocation loc = openClosedList.Lookup(env->GetStateHash(val), theID);
640 gCost = openClosedList.Lookat(theID).g;
646 template <
class state,
class action,
class environment,
class openList>
650 dataLocation loc = openClosedList.Lookup(env->GetStateHash(val), theID);
653 gCost = openClosedList.Lookat(theID).g;
659 template <
class state,
class action,
class environment,
class openList>
663 dataLocation loc = openClosedList.Lookup(env->GetStateHash(val), theID);
666 hCost = openClosedList.Lookat(theID).h;
672 template <
class state,
class action,
class environment,
class openList>
679 result = openClosedList.Lookat(theID);
693 template <
class state,
class action,
class environment,
class openList>
696 double transparency = 1.0;
697 if (openClosedList.size() == 0)
701 if (openClosedList.OpenSize() > 0)
703 top = openClosedList.Peek();
714 for (
unsigned int x = 0; x < openClosedList.size(); x++)
716 const auto &data = openClosedList.Lookat(x);
719 env->SetColor(1.0, 1.0, 0.0, transparency);
720 env->OpenGLDraw(data.data);
722 if ((data.where ==
kOpenList) && (data.reopened))
724 env->SetColor(0.0, 0.5, 0.5, transparency);
725 env->OpenGLDraw(data.data);
729 env->SetColor(0.0, 1.0, 0.0, transparency);
730 env->OpenGLDraw(data.data);
732 else if ((data.where ==
kClosedList) && (data.reopened))
734 env->SetColor(0.5, 0.0, 0.5, transparency);
735 env->OpenGLDraw(data.data);
744 if (data.parentID == x)
745 env->SetColor(1.0, 0.5, 0.5, transparency);
747 env->SetColor(1.0, 0.0, 0.0, transparency);
749 env->OpenGLDraw(data.data);
752 env->SetColor(1.0, 0.5, 1.0, 0.5);
753 env->OpenGLDraw(goal);
762 template <
class state,
class action,
class environment,
class openList>
765 double transparency = 1.0;
766 if (openClosedList.size() == 0)
770 if (openClosedList.OpenSize() > 0)
772 top = openClosedList.Peek();
774 for (
unsigned int x = 0; x < openClosedList.size(); x++)
776 const auto &data = openClosedList.Lookat(x);
779 env->SetColor(1.0, 1.0, 0.0, transparency);
780 env->Draw(disp, data.
data);
782 else if ((data.where ==
kOpenList) && (data.reopened))
784 env->SetColor(0.0, 0.5, 0.5, transparency);
785 env->Draw(disp, data.
data);
789 env->SetColor(0.0, 1.0, 0.0, transparency);
790 env->Draw(disp, data.
data);
792 else if ((data.where ==
kClosedList) && (data.reopened))
794 env->SetColor(0.5, 0.0, 0.5, transparency);
795 env->Draw(disp, data.
data);
804 if (data.parentID == x)
805 env->SetColor(1.0, 0.5, 0.5, transparency);
807 env->SetColor(1.0, 0.0, 0.0, transparency);
809 env->Draw(disp, data.
data);
812 env->SetColor(1.0, 0.5, 1.0, 0.5);
813 env->Draw(disp, goal);
816 template <
class state,
class action,
class environment,
class openList>
820 double transparency = 1.0;
821 if (openClosedList.size() == 0)
825 if (openClosedList.OpenSize() > 0)
827 top = openClosedList.Peek();
829 for (
unsigned int x = 0; x < openClosedList.size(); x++)
831 const auto &data = openClosedList.Lookat(x);
835 env->SetColor(1.0, 1.0, 0.0, transparency);
836 s+=env->SVGDraw(data.data);
838 else if ((data.where ==
kOpenList) && (data.reopened))
840 env->SetColor(0.0, 0.5, 0.5, transparency);
841 s+=env->SVGDraw(data.data);
845 env->SetColor(0.0, 1.0, 0.0, transparency);
846 s+=env->SVGDraw(data.data);
848 else if ((data.where ==
kClosedList) && (data.reopened))
850 env->SetColor(0.5, 0.0, 0.5, transparency);
851 s+=env->SVGDraw(data.data);
855 env->SetColor(1.0, 0.0, 0.0, transparency);
856 s+=env->SVGDraw(data.data);
862 template <
class state,
class action,
class environment,
class openList>
867 if (openClosedList.size() == 0)
871 if (openClosedList.OpenSize() > 0)
873 top = openClosedList.Peek();
875 for (
unsigned int x = 0; x < openClosedList.size(); x++)
877 const auto &data = openClosedList.Lookat(x);
904 env->SetColor(0.0, 0.0, 0.0);
906 sprintf(
d,
"%1.1f", data.g+data.h);
907 s+=env->SVGLabelState(data.data,
d, 0.35, -0.6, -1.1);
908 sprintf(
d,
"g:%1.1f", data.g);
909 s+=env->SVGLabelState(data.data,
d, 0.25, -0.6, -0.75);
910 sprintf(
d,
"h:%1.1f", data.h);
911 s+=env->SVGLabelState(data.data,
d, 0.25, -0.6, -0.48);