15 #include <unordered_map>
17 template<
typename state>
34 template <
class state,
int epsilon = 0>
53 template <>
struct hash<
std::pair<double, double>>
55 size_t operator()(
const std::pair<double, double> & x)
const
57 return std::hash<double>()(x.first)^(std::hash<double>()(x.second)<<16);
63 template <
class state,
class action,
class environment,
class priorityQueue = AStarOpenClosed<state, fMMCompare<state>, FMMOpenClosedData<state>> >
69 void GetPath(environment *
env,
const state& from,
const state& to,
75 virtual const char *
GetName() {
return "fMM"; }
95 std::vector<uint64_t>
d;
96 for (
auto i =
dist.begin(); i !=
dist.end(); i++)
98 if (i->first.first < i->first.second)
100 int h = (int)i->first.second;
106 printf(
"fMM Dynamic Distribution\n");
107 for (
int x = 0; x <
d.size(); x++)
110 printf(
"%d\t%" PRId64
"\n", x,
d[x]);
115 printf(
"Search distributions: (%s)\n", ((&s)==(&
f))?
"forward":
"backward");
116 for (
auto i = s.begin(); i != s.end(); i++)
121 ignore = (i->first.first+i->first.second >=
currentCost);
122 printf(
"%c g: %1.1f h: %1.1f count: %d\n", ignore?
'*':
' ',
123 i->first.first, i->first.second, i->second);
154 void OpenGLDraw(
const priorityQueue &queue)
const;
155 std::string
SVGDraw(
const priorityQueue &queue)
const;
157 void Expand(priorityQueue ¤t,
158 priorityQueue &opposite,
161 std::unordered_map<std::pair<double, double>,
int> &count);
166 std::unordered_map<std::pair<double, double>,
int>
dist;
167 std::unordered_map<std::pair<double, double>,
int>
f,
b;
187 template <
class state,
class action,
class environment,
class priorityQueue>
191 if (InitializeSearch(env, from, to, forward, backward, thePath) ==
false)
194 while (!DoSingleSearchStep(thePath))
198 template <
class state,
class action,
class environment,
class priorityQueue>
201 std::vector<state> &thePath)
204 forwardHeuristic = forward;
205 backwardHeuristic = backward;
206 currentCost = DBL_MAX;
207 forwardQueue.Reset();
208 backwardQueue.Reset();
217 lastMinBackwardG = 0;
221 i = forwardQueue.AddOpenNode(start, env->GetStateHash(start), 0, forwardHeuristic->HCost(start, goal));
222 forwardQueue.Lookup(i).frac = fraction;
223 backwardQueue.AddOpenNode(goal, env->GetStateHash(goal), 0, backwardHeuristic->HCost(goal, start));
224 backwardQueue.Lookup(i).frac = 1-fraction;
232 template <
class state,
class action,
class environment,
class priorityQueue>
235 if (forwardQueue.OpenSize() == 0 || backwardQueue.OpenSize() == 0)
248 uint64_t forward = forwardQueue.Peek();
249 uint64_t backward = backwardQueue.Peek();
254 double p1 =
std::max(nextForward.
g+nextForward.
h, nextForward.
g/nextForward.
frac);
255 if (nextForward.
frac == 0)
257 double p2 =
std::max(nextBackward.
g+nextBackward.
h, nextBackward.
g/nextBackward.
frac);
258 if (nextBackward.
frac == 0)
277 Expand(forwardQueue, backwardQueue, forwardHeuristic, goal, f);
279 else if (
fless(p2, p1))
283 Expand(backwardQueue, forwardQueue, backwardHeuristic, start, b);
293 Expand(forwardQueue, backwardQueue, forwardHeuristic, goal, f);
295 else if (!
fequal(nextBackward.
g/nextBackward.
frac, p2))
297 Expand(backwardQueue, forwardQueue, backwardHeuristic, start, b);
300 Expand(forwardQueue, backwardQueue, forwardHeuristic, goal, f);
309 double minForwardG = DBL_MAX;
310 double minBackwardG = DBL_MAX;
311 double minForwardF = DBL_MAX;
312 double minBackwardF = DBL_MAX;
316 for (
auto i = f.begin(); i != f.end(); i++)
320 if ((i->first.first + i->first.second < currentCost) &&
321 (i->first.first + lastMinBackwardG + 1.0 < currentCost))
323 minForwardG =
std::min(minForwardG, i->first.first);
324 minForwardF =
std::min(minForwardF, i->first.first+i->first.second);
328 for (
auto i = b.begin(); i != b.end(); i++)
332 if ((i->first.first + i->first.second < currentCost) &&
333 (i->first.first + lastMinForwardG + 1.0 < currentCost))
335 minBackwardG =
std::min(minBackwardG, i->first.first);
336 minBackwardF =
std::min(minBackwardF, i->first.first+i->first.second);
342 auto iB = backwardQueue.Lookat(backwardQueue.Peek());
343 backwardP =
std::max(iB.g+iB.h, iB.g/iB.frac);
344 auto iF = forwardQueue.Lookat(forwardQueue.Peek());
345 forwardP =
std::max(iF.g+iF.h, iF.g/iF.frac);
348 if (minForwardF == DBL_MAX)
350 minForwardF = minForwardG = currentCost+1;
352 if (minBackwardF == DBL_MAX)
354 minBackwardF = minBackwardG = currentCost+1;
356 if (!
fgreater(currentCost, minForwardF))
361 if (!
fgreater(currentCost, minBackwardF))
366 if (!
fgreater(currentCost, minForwardG+minBackwardG+epsilon))
382 lastMinBackwardG = minBackwardG;
383 lastMinForwardG = minForwardG;
389 std::vector<state> pFor, pBack;
390 ExtractPathToGoal(middleNode, pBack);
391 ExtractPathToStart(middleNode, pFor);
392 reverse(pFor.begin(), pFor.end());
394 thePath.insert( thePath.end(), pBack.begin()+1, pBack.end() );
402 template <
class state,
class action,
class environment,
class priorityQueue>
404 priorityQueue &opposite,
406 std::unordered_map<std::pair<double, double>,
int> &count)
408 uint64_t nextID = current.Close();
410 if (current.Lookup(nextID).reopened ==
false)
411 uniqueNodesExpanded++;
415 auto &i = current.Lookup(nextID);
416 std::cout <<
"Expanding " << i.data <<
"\n";
417 printf(
"g: %1.1f, h:%1.1f, pr:%1.1f\n", current.Lookup(nextID).g, current.Lookup(nextID).h,
std::max((i.g+i.h), i.g/i.frac));
422 auto &parentData = current.Lookup(nextID);
423 count[{parentData.g,parentData.h}]--;
424 if (count[{parentData.g,parentData.h}] == 0 && currentCost < DBL_MAX)
430 env->GetSuccessors(current.Lookup(nextID).data, neighbors);
431 for (
auto &succ : neighbors)
435 uint64_t hash = env->GetStateHash(succ);
436 auto loc = current.Lookup(hash, childID);
437 auto &childData = current.Lookup(childID);
438 auto &parentData = current.Lookup(nextID);
440 double edgeCost = env->GCost(parentData.data, succ);
444 if (
fless(parentData.g+edgeCost, childData.g))
446 childData.h =
std::max(childData.h, parentData.h-edgeCost);
447 childData.parentID = nextID;
448 childData.g = parentData.g+edgeCost;
449 count[{childData.g,childData.h}]++;
450 dist[{childData.g,childData.h}]++;
451 current.Reopen(childID);
457 parentData.h =
std::max(childData.h-edgeCost, parentData.h);
459 if (
fgreater(parentData.h-edgeCost, childData.h))
461 count[{childData.g,childData.h}]--;
462 dist[{childData.g,childData.h}]--;
464 childData.h = parentData.h-edgeCost;
466 count[{childData.g,childData.h}]++;
467 dist[{childData.g,childData.h}]++;
469 if (
fless(parentData.g+edgeCost, childData.g))
471 count[{childData.g,childData.h}]--;
472 dist[{childData.g,childData.h}]--;
473 childData.parentID = nextID;
474 childData.g = parentData.g+edgeCost;
475 current.KeyChanged(childID);
476 count[{childData.g,childData.h}]++;
477 dist[{childData.g,childData.h}]++;
482 auto loc = opposite.Lookup(hash, reverseLoc);
485 if (
fless(parentData.g+edgeCost + opposite.Lookup(reverseLoc).g, currentCost))
489 printf(
"Potential updated solution found, cost: %1.2f + %1.2f = %1.2f\n",
490 parentData.g+edgeCost,
491 opposite.Lookup(reverseLoc).g,
492 parentData.g+edgeCost+opposite.Lookup(reverseLoc).g);
493 currentCost = parentData.g+edgeCost + opposite.Lookup(reverseLoc).g;
504 double g = parentData.g+edgeCost;
505 double h =
std::max(heuristic->
HCost(succ, target), parentData.h-edgeCost);
508 if (!
fless(g+h, currentCost))
515 parentData.h =
std::max(h-edgeCost, parentData.h);
518 i = current.AddOpenNode(succ,
523 if (¤t == &forwardQueue)
524 current.Lookup(i).frac = fraction;
526 current.Lookup(i).frac = 1-fraction;
530 auto loc = opposite.Lookup(hash, reverseLoc);
533 if (
fless(current.Lookup(nextID).g+edgeCost + opposite.Lookup(reverseLoc).g, currentCost))
537 printf(
"Potential solution found, cost: %1.2f + %1.2f = %1.2f\n",
538 current.Lookup(nextID).g+edgeCost,
539 opposite.Lookup(reverseLoc).g,
540 current.Lookup(nextID).g+edgeCost+opposite.Lookup(reverseLoc).g);
541 currentCost = current.Lookup(nextID).g+edgeCost + opposite.Lookup(reverseLoc).g;
552 template <
class state,
class action,
class environment,
class priorityQueue>
556 for (
unsigned int x = 0; x < forwardQueue.size(); x++)
562 for (
unsigned int x = 0; x < backwardQueue.size(); x++)
571 template <
class state,
class action,
class environment,
class priorityQueue>
574 OpenGLDraw(forwardQueue);
575 OpenGLDraw(backwardQueue);
578 template <
class state,
class action,
class environment,
class priorityQueue>
581 double transparency = 0.9;
582 if (queue.size() == 0)
586 if (queue.OpenSize() > 0)
590 for (
unsigned int x = 0; x < queue.size(); x++)
595 env->SetColor(1.0, 1.0, 0.0, transparency);
596 env->OpenGLDraw(data.
data);
600 env->SetColor(0.0, 0.5, 0.5, transparency);
601 env->OpenGLDraw(data.
data);
605 env->SetColor(0.0, 1.0, 0.0, transparency);
606 env->OpenGLDraw(data.
data);
610 env->SetColor(0.5, 0.0, 0.5, transparency);
611 env->OpenGLDraw(data.
data);
615 env->SetColor(1.0, 0.0, 0.0, transparency);
616 env->OpenGLDraw(data.
data);
621 template <
class state,
class action,
class environment,
class priorityQueue>
625 s += SVGDraw(forwardQueue);
626 s += SVGDraw(backwardQueue);
630 template <
class state,
class action,
class environment,
class priorityQueue>
634 double transparency = 1.0;
635 if (queue.size() == 0)
639 if (queue.OpenSize() > 0)
643 for (
unsigned int x = 0; x < queue.size(); x++)
645 const auto &data = queue.Lookat(x);
649 env->SetColor(1.0, 1.0, 0.0, transparency);
650 s+=env->SVGDraw(data.data);
652 else if ((data.where ==
kOpenList) && (data.reopened))
654 env->SetColor(0.0, 0.5, 0.5, transparency);
655 s+=env->SVGDraw(data.data);
659 env->SetColor(0.0, 1.0, 0.0, transparency);
660 s+=env->SVGDraw(data.data);
662 else if ((data.where ==
kClosedList) && (data.reopened))
664 env->SetColor(0.5, 0.0, 0.5, transparency);
665 s+=env->SVGDraw(data.data);
669 env->SetColor(1.0, 0.0, 0.0, transparency);
670 s+=env->SVGDraw(data.data);
677 template <
class state,
class action,
class environment,
class priorityQueue>
680 Draw(display, forwardQueue);
681 Draw(display, backwardQueue);
684 template <
class state,
class action,
class environment,
class priorityQueue>
687 double transparency = 0.9;
688 if (queue.size() == 0)
692 if (queue.OpenSize() > 0)
696 for (
unsigned int x = 0; x < queue.size(); x++)
698 const auto &data = queue.Lookat(x);
701 env->SetColor(1.0, 1.0, 0.0, transparency);
702 env->Draw(display, data.
data);
704 if ((data.where ==
kOpenList) && (data.reopened))
706 env->SetColor(0.0, 0.5, 0.5, transparency);
707 env->Draw(display, data.
data);
711 env->SetColor(0.0, 1.0, 0.0, transparency);
712 env->Draw(display,data.
data);
714 else if ((data.where ==
kClosedList) && (data.reopened))
716 env->SetColor(0.5, 0.0, 0.5, transparency);
717 env->Draw(display,data.
data);
721 env->SetColor(1.0, 0.0, 0.0, transparency);
722 env->Draw(display, data.
data);