15 #include <unordered_map>
18 template <
class state,
int epsilon = 1>
34 template <>
struct hash<
std::pair<double, double>>
36 size_t operator()(
const std::pair<double, double> & x)
const
38 return std::hash<double>()(x.first)^(std::hash<double>()(x.second)<<16);
44 template <
class state,
class action,
class environment,
class priorityQueue = AStarOpenClosed<state, MMCompare<state>> >
49 void GetPath(environment *
env,
const state& from,
const state& to,
55 virtual const char *
GetName() {
return "MM"; }
74 std::vector<uint64_t>
d;
75 for (
auto i =
dist.begin(); i !=
dist.end(); i++)
77 if (i->first.first < i->first.second)
79 int h = (int)i->first.second;
85 printf(
"MM Dynamic Distribution\n");
86 for (
int x = 0; x <
d.size(); x++)
89 printf(
"%d\t%" PRId64
"\n", x,
d[x]);
94 printf(
"Search distributions: (%s)\n", ((&s)==(&
f))?
"forward":
"backward");
95 for (
auto i = s.begin(); i != s.end(); i++)
100 ignore = (i->first.first+i->first.second >=
currentCost);
101 printf(
"%c g: %1.1f h: %1.1f count: %d\n", ignore?
'*':
' ',
102 i->first.first, i->first.second, i->second);
132 void OpenGLDraw(
const priorityQueue &queue)
const;
133 std::string
SVGDraw(
const priorityQueue &queue)
const;
135 void Expand(priorityQueue ¤t,
136 priorityQueue &opposite,
139 std::unordered_map<std::pair<double, double>,
int> &count);
144 std::unordered_map<std::pair<double, double>,
int>
dist;
145 std::unordered_map<std::pair<double, double>,
int>
f,
b;
164 template <
class state,
class action,
class environment,
class priorityQueue>
168 if (InitializeSearch(env, from, to, forward, backward, thePath) ==
false)
171 while (!DoSingleSearchStep(thePath))
175 template <
class state,
class action,
class environment,
class priorityQueue>
178 std::vector<state> &thePath)
181 forwardHeuristic = forward;
182 backwardHeuristic = backward;
183 currentCost = DBL_MAX;
184 forwardQueue.Reset();
185 backwardQueue.Reset();
194 lastMinBackwardG = 0;
195 forwardQueue.AddOpenNode(start, env->GetStateHash(start), 0, forwardHeuristic->HCost(start, goal));
196 backwardQueue.AddOpenNode(goal, env->GetStateHash(goal), 0, backwardHeuristic->HCost(goal, start));
203 template <
class state,
class action,
class environment,
class priorityQueue>
206 if (forwardQueue.OpenSize() == 0 || backwardQueue.OpenSize() == 0)
219 uint64_t forward = forwardQueue.Peek();
220 uint64_t backward = backwardQueue.Peek();
225 double p1 =
std::max(nextForward.
g+nextForward.
h, nextForward.
g*2);
226 double p2 =
std::max(nextBackward.
g+nextBackward.
h, nextBackward.
g*2);
243 Expand(forwardQueue, backwardQueue, forwardHeuristic, goal, f);
245 else if (
fless(p2, p1))
248 Expand(backwardQueue, forwardQueue, backwardHeuristic, start, b);
251 if (
fless(nextForward.
g, nextBackward.
g))
254 Expand(forwardQueue, backwardQueue, forwardHeuristic, goal, f);
256 else if (
fless(nextBackward.
g, nextForward.
g))
259 Expand(backwardQueue, forwardQueue, backwardHeuristic, start, b);
262 Expand(forwardQueue, backwardQueue, forwardHeuristic, goal, f);
271 double minForwardG = DBL_MAX;
272 double minBackwardG = DBL_MAX;
273 double minForwardF = DBL_MAX;
274 double minBackwardF = DBL_MAX;
278 for (
auto i = f.begin(); i != f.end(); i++)
282 if ((i->first.first + i->first.second < currentCost) &&
283 (i->first.first + lastMinBackwardG + 1.0 < currentCost))
285 minForwardG =
std::min(minForwardG, i->first.first);
286 minForwardF =
std::min(minForwardF, i->first.first+i->first.second);
290 for (
auto i = b.begin(); i != b.end(); i++)
294 if ((i->first.first + i->first.second < currentCost) &&
295 (i->first.first + lastMinForwardG + 1.0 < currentCost))
297 minBackwardG =
std::min(minBackwardG, i->first.first);
298 minBackwardF =
std::min(minBackwardF, i->first.first+i->first.second);
304 auto iB = backwardQueue.Lookat(backwardQueue.Peek());
305 backwardP =
std::max(iB.g+iB.h, iB.g*2);
306 auto iF = forwardQueue.Lookat(forwardQueue.Peek());
307 forwardP =
std::max(iF.g+iF.h, iF.g*2);
310 if (minForwardF == DBL_MAX)
312 minForwardF = minForwardG = currentCost+1;
314 if (minBackwardF == DBL_MAX)
316 minBackwardF = minBackwardG = currentCost+1;
318 if (!
fgreater(currentCost, minForwardF))
323 if (!
fgreater(currentCost, minBackwardF))
328 if (!
fgreater(currentCost, minForwardG+minBackwardG+epsilon))
344 lastMinBackwardG = minBackwardG;
345 lastMinForwardG = minForwardG;
351 std::vector<state> pFor, pBack;
352 ExtractPathToGoal(middleNode, pBack);
353 ExtractPathToStart(middleNode, pFor);
354 reverse(pFor.begin(), pFor.end());
356 thePath.insert( thePath.end(), pBack.begin()+1, pBack.end() );
364 template <
class state,
class action,
class environment,
class priorityQueue>
366 priorityQueue &opposite,
368 std::unordered_map<std::pair<double, double>,
int> &count)
372 uint64_t nextID = current.Close();
374 if (current.Lookup(nextID).reopened ==
false)
375 uniqueNodesExpanded++;
379 auto &parentData = current.Lookup(nextID);
380 count[{parentData.g,parentData.h}]--;
381 if (count[{parentData.g,parentData.h}] == 0 && currentCost < DBL_MAX)
387 env->GetSuccessors(current.Lookup(nextID).data, neighbors);
388 for (
auto &succ : neighbors)
392 uint64_t hash = env->GetStateHash(succ);
393 auto loc = current.Lookup(hash, childID);
394 auto &childData = current.Lookup(childID);
395 auto &parentData = current.Lookup(nextID);
397 double edgeCost = env->GCost(parentData.data, succ);
401 if (
fless(parentData.g+edgeCost, childData.g))
403 childData.h =
std::max(childData.h, parentData.h-edgeCost);
404 childData.parentID = nextID;
405 childData.g = parentData.g+edgeCost;
406 count[{childData.g,childData.h}]++;
407 dist[{childData.g,childData.h}]++;
408 current.Reopen(childID);
414 parentData.h =
std::max(childData.h-edgeCost, parentData.h);
416 if (
fgreater(parentData.h-edgeCost, childData.h))
418 count[{childData.g,childData.h}]--;
419 dist[{childData.g,childData.h}]--;
421 childData.h = parentData.h-edgeCost;
423 count[{childData.g,childData.h}]++;
424 dist[{childData.g,childData.h}]++;
426 if (
fless(parentData.g+edgeCost, childData.g))
428 count[{childData.g,childData.h}]--;
429 dist[{childData.g,childData.h}]--;
430 childData.parentID = nextID;
431 childData.g = parentData.g+edgeCost;
432 current.KeyChanged(childID);
433 count[{childData.g,childData.h}]++;
434 dist[{childData.g,childData.h}]++;
439 auto loc = opposite.Lookup(hash, reverseLoc);
442 if (
fless(parentData.g+edgeCost + opposite.Lookup(reverseLoc).g, currentCost))
450 currentCost = parentData.g+edgeCost + opposite.Lookup(reverseLoc).g;
461 double g = parentData.g+edgeCost;
462 double h =
std::max(heuristic->
HCost(succ, target), parentData.h-edgeCost);
465 if (!
fless(g+h, currentCost))
472 parentData.h =
std::max(h-edgeCost, parentData.h);
474 current.AddOpenNode(succ,
482 auto loc = opposite.Lookup(hash, reverseLoc);
485 if (
fless(current.Lookup(nextID).g+edgeCost + opposite.Lookup(reverseLoc).g, currentCost))
493 currentCost = current.Lookup(nextID).g+edgeCost + opposite.Lookup(reverseLoc).g;
504 template <
class state,
class action,
class environment,
class priorityQueue>
508 for (
unsigned int x = 0; x < forwardQueue.size(); x++)
514 for (
unsigned int x = 0; x < backwardQueue.size(); x++)
523 template <
class state,
class action,
class environment,
class priorityQueue>
526 OpenGLDraw(forwardQueue);
527 OpenGLDraw(backwardQueue);
530 template <
class state,
class action,
class environment,
class priorityQueue>
533 double transparency = 0.9;
534 if (queue.size() == 0)
538 if (queue.OpenSize() > 0)
542 for (
unsigned int x = 0; x < queue.size(); x++)
547 env->SetColor(1.0, 1.0, 0.0, transparency);
548 env->OpenGLDraw(data.
data);
552 env->SetColor(0.0, 0.5, 0.5, transparency);
553 env->OpenGLDraw(data.
data);
557 env->SetColor(0.0, 1.0, 0.0, transparency);
558 env->OpenGLDraw(data.
data);
562 env->SetColor(0.5, 0.0, 0.5, transparency);
563 env->OpenGLDraw(data.
data);
567 env->SetColor(1.0, 0.0, 0.0, transparency);
568 env->OpenGLDraw(data.
data);
573 template <
class state,
class action,
class environment,
class priorityQueue>
577 s += SVGDraw(forwardQueue);
578 s += SVGDraw(backwardQueue);
582 template <
class state,
class action,
class environment,
class priorityQueue>
586 double transparency = 1.0;
587 if (queue.size() == 0)
591 if (queue.OpenSize() > 0)
595 for (
unsigned int x = 0; x < queue.size(); x++)
597 const auto &data = queue.Lookat(x);
601 env->SetColor(1.0, 1.0, 0.0, transparency);
602 s+=env->SVGDraw(data.data);
604 else if ((data.where ==
kOpenList) && (data.reopened))
606 env->SetColor(0.0, 0.5, 0.5, transparency);
607 s+=env->SVGDraw(data.data);
611 env->SetColor(0.0, 1.0, 0.0, transparency);
612 s+=env->SVGDraw(data.data);
614 else if ((data.where ==
kClosedList) && (data.reopened))
616 env->SetColor(0.5, 0.0, 0.5, transparency);
617 s+=env->SVGDraw(data.data);
621 env->SetColor(1.0, 0.0, 0.0, transparency);
622 s+=env->SVGDraw(data.data);