9 #ifndef hog2_glut_ParallelIDA_h
10 #define hog2_glut_ParallelIDA_h
14 #include <unordered_map>
22 template <
class action>
33 template <
class environment,
class state,
class action>
40 void GetPath(environment *env, state from, state to,
41 std::vector<action> &thePath);
52 action forbiddenAction, state &currState,
53 std::vector<action> &thePath,
double bound,
double g,
56 action forbiddenAction, state &currState,
57 std::vector<action> &thePath);
62 uint64_t early = 0, late = 0;
63 printf(
"G-cost distribution\n");
74 printf(
"--Strong heuristic - Expect MM > A*\n");
76 printf(
"--Weak heuristic - Expect MM >= MM0.\n");
78 printf(
"F-cost distribution\n");
94 std::vector<workUnit<action>>
work;
108 template <
class environment,
class state,
class action>
110 state from, state to,
111 std::vector<action> &thePath)
113 const auto numThreads = std::thread::hardware_concurrency();
114 if (!storedHeuristic)
117 nodesExpanded = nodesTouched = 0;
124 if (env->GoalTest(from, to))
127 std::vector<action> act;
128 env->GetActions(from, act);
130 double rootH = heuristic->HCost(from, to);
131 UpdateNextBound(0, rootH);
135 GenerateWork(env, act[0], from, thePath);
136 for (
size_t x = 0; x < work.size(); x++)
137 work[x].unitNumber = x;
138 printf(
"%lu pieces of work generated\n", work.size());
139 foundSolution = work.size() + 1;
141 while (foundSolution > work.size())
143 gCostHistogram.clear();
144 gCostHistogram.resize(nextBound+1);
145 fCostHistogram.clear();
146 fCostHistogram.resize(nextBound+1);
149 printf(
"Starting iteration with bound %f; %" PRId64
" expanded, %" PRId64
" generated\n", nextBound, nodesExpanded, nodesTouched);
152 for (
size_t x = 0; x < work.size(); x++)
156 for (
size_t x = 0; x < numThreads; x++)
159 *env, from, nextBound));
161 for (
int x = 0; x < threads.size(); x++)
167 double bestBound = (nextBound+1)*10;
168 for (
int x = 0; x < work.size(); x++)
170 for (
int y = 0; y < work[x].gHistogram.size(); y++)
172 gCostHistogram[y] += work[x].gHistogram[y];
173 fCostHistogram[y] += work[x].fHistogram[y];
175 if (work[x].nextBound > nextBound && work[x].nextBound < bestBound)
178 bestBound = work[x].nextBound;
180 nodesExpanded += work[x].expanded;
181 nodesTouched += work[x].touched;
182 if (work[x].solution.size() != 0)
187 thePath = work[x].solution;
190 nextBound = bestBound;
194 if (thePath.size() != 0)
199 template <
class environment,
class state,
class action>
201 action forbiddenAction, state &currState,
202 std::vector<action> &thePath)
209 w.
pre[x] = thePath[x];
215 std::vector<action> actions;
216 env->GetActions(currState, actions);
217 nodesTouched += actions.size();
219 int depth = (int)thePath.size();
221 for (
unsigned int x = 0; x < actions.size(); x++)
223 if ((depth != 0) && (actions[x] == forbiddenAction))
226 thePath.push_back(actions[x]);
228 env->ApplyAction(currState, actions[x]);
231 action a = actions[x];
232 env->InvertAction(a);
233 GenerateWork(env, a, currState, thePath);
234 env->UndoAction(currState, actions[x]);
240 template <
class environment,
class state,
class action>
244 std::vector<action> thePath;
249 if (q.Remove(nextValue) ==
false)
253 bool passedLimit =
false;
267 g += env.GCost(startState, localWork.
pre[x]);
268 env.ApplyAction(startState, localWork.
pre[x]);
269 thePath.push_back(localWork.
pre[x]);
271 if (!passedLimit &&
fgreater(g+heuristic->HCost(startState, goal), bound))
273 localWork.
nextBound = g+heuristic->HCost(startState, goal);
279 env.InvertAction(last);
283 DoIteration(&env, last, startState, thePath, bound, g, localWork, actCache);
288 env.UndoAction(startState, localWork.
pre[x]);
289 g -= env.GCost(startState, localWork.
pre[x]);
291 work[nextValue] = localWork;
296 template <
class environment,
class state,
class action>
298 action forbiddenAction, state &currState,
299 std::vector<action> &thePath,
double bound,
double g,
302 double h = heuristic->HCost(currState, goal);
312 if (env->GoalTest(currState, goal))
319 std::vector<action> &actions = *cache.
getItem();
320 env->GetActions(currState, actions);
326 for (
unsigned int x = 0; x < actions.size(); x++)
328 if (actions[x] == forbiddenAction)
331 thePath.push_back(actions[x]);
333 double edgeCost = env->GCost(currState, actions[x]);
334 env->ApplyAction(currState, actions[x]);
335 action a = actions[x];
336 env->InvertAction(a);
337 DoIteration(env, a, currState, thePath, bound, g+edgeCost, w, cache);
338 env->UndoAction(currState, actions[x]);
347 template <
class environment,
class state,
class action>
350 if (!
fgreater(nextBound, currBound))
355 else if (
fgreater(fCost, currBound) &&
fless(fCost, nextBound))