HOG2
IDAStar.h
Go to the documentation of this file.
1 /*
2  * IDAStar.h
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 5/22/07.
6  * Copyright 2007 Nathan Sturtevant, University of Alberta. All rights reserved.
7  *
8  */
9 
10 #ifndef IDASTAR_H
11 #define IDASTAR_H
12 
13 #include <iostream>
14 #include <functional>
15 #include "SearchEnvironment.h"
16 #include <unordered_map>
17 #include <cinttypes>
18 #include "FPUtil.h"
19 #include "vectorCache.h"
20 
21 //#define DO_LOGGING
22 
23 typedef std::unordered_map<uint64_t, double> NodeHashTable;
24 
25 template <class state, class action, bool verbose = true>
26 class IDAStar {
27 public:
29  virtual ~IDAStar() {}
30  void GetPath(SearchEnvironment<state, action> *env, state from, state to,
31  std::vector<state> &thePath);
32  void GetPath(SearchEnvironment<state, action> *env, state from, state to,
33  std::vector<action> &thePath);
34 
35  uint64_t GetNodesExpanded() { return nodesExpanded; }
36  uint64_t GetNodesTouched() { return nodesTouched; }
38  void SetUseBDPathMax(bool val) { usePathMax = val; }
39  void SetHeuristic(Heuristic<state> *heur) { heuristic = heur; if (heur != 0) storedHeuristic = true;}
40 private:
41  unsigned long long nodesExpanded, nodesTouched;
42 
44  state parent, state currState,
45  std::vector<state> &thePath, double bound, double g,
46  double maxH);
48  action forbiddenAction, state &currState,
49  std::vector<action> &thePath, double bound, double g,
50  double maxH, double parentH);
52  {
53 // uint64_t early = 0, late = 0;
54 // for (int x = 0; x < gCostHistogram.size(); x++)
55 // {
56 // printf("%d\t%" PRId64 "\n", x, gCostHistogram[x]);
57 // if (x*2 > gCostHistogram.size()-1)
58 // late += gCostHistogram[x];
59 // else
60 // early += gCostHistogram[x];
61 // }
62 // if (late < early)
63 // printf("Strong heuristic - Expect MM > A*\n");
64 // else
65 // printf("Weak heuristic - Expect MM >= MM0.\n");
66  }
67  void UpdateNextBound(double currBound, double fCost);
68  state goal;
69  double nextBound;
70  //NodeHashTable nodeTable;
71  bool usePathMax;
76  std::vector<uint64_t> gCostHistogram;
77 
78 #ifdef DO_LOGGING
79 public:
80  std::function<void (state, int)> func;
81 #endif
82 };
83 
84 template <class state, class action, bool verbose>
86  state from, state to,
87  std::vector<state> &thePath)
88 {
89  if (!storedHeuristic)
90  heuristic = env;
91  nextBound = 0;
92  nodesExpanded = nodesTouched = 0;
93  thePath.resize(0);
94  UpdateNextBound(0, heuristic->HCost(from, to));
95  goal = to;
96  thePath.push_back(from);
97  while (true) //thePath.size() == 0)
98  {
99  //nodeTable.clear();
100  gCostHistogram.clear();
101  gCostHistogram.resize(nextBound+1);
102  if (verbose)
103  printf("Starting iteration with bound %f\n", nextBound);
104  if (DoIteration(env, from, from, thePath, nextBound, 0, 0) == 0)
105  break;
106  PrintGHistogram();
107  }
108  PrintGHistogram();
109 }
110 
111 template <class state, class action, bool verbose>
113  state from, state to,
114  std::vector<action> &thePath)
115 {
116  if (!storedHeuristic)
117  heuristic = env;
118  nextBound = 0;
119  nodesExpanded = nodesTouched = 0;
120  thePath.resize(0);
121 
122  if (env->GoalTest(from, to))
123  return;
124 
125  double rootH = heuristic->HCost(from, to);
126  UpdateNextBound(0, rootH);
127  goal = to;
128  std::vector<action> act;
129  env->GetActions(from, act);
130  while (thePath.size() == 0)
131  {
132  //nodeTable.clear();
133  gCostHistogram.clear();
134  gCostHistogram.resize(nextBound+1);
135  if (verbose)
136  printf("Starting iteration with bound %f; %" PRId64 " expanded, %" PRId64 " generated\n", nextBound, nodesExpanded, nodesTouched);
137  fflush(stdout);
138  DoIteration(env, act[0], from, thePath, nextBound, 0, 0, rootH);
139  PrintGHistogram();
140  }
141 }
142 
143 template <class state, class action, bool verbose>
145  state parent, state currState,
146  std::vector<state> &thePath, double bound, double g,
147  double maxH)
148 {
149  double h = heuristic->HCost(currState, goal);
150  // path max
151  if (usePathMax && fless(h, maxH))
152  h = maxH;
153  if (fgreater(g+h, bound))
154  {
155  UpdateNextBound(bound, g+h);
156  //printf("Stopping at (%d, %d). g=%f h=%f\n", currState>>16, currState&0xFFFF, g, h);
157  return h;
158  }
159  if (env->GoalTest(currState, goal))
160  return 0;
161 
162  std::vector<state> neighbors;
163  env->GetSuccessors(currState, neighbors);
164  nodesTouched += neighbors.size();
165  nodesExpanded++;
166  gCostHistogram[g]++;
167 
168  for (unsigned int x = 0; x < neighbors.size(); x++)
169  {
170  if (neighbors[x] == parent)
171  continue;
172  thePath.push_back(neighbors[x]);
173  double edgeCost = env->GCost(currState, neighbors[x]);
174  double childH = DoIteration(env, currState, neighbors[x], thePath, bound,
175  g+edgeCost, maxH - edgeCost);
176  if (env->GoalTest(thePath.back(), goal) && flesseq(g+edgeCost,bound)) //check that a solution that does not exceed the bound was found
177  return 0;
178  thePath.pop_back();
179  // pathmax
180  if (usePathMax && fgreater(childH-edgeCost, h))
181  {
182 // nodeTable[currState] = g;//+h
183  h = childH-edgeCost;
184  if (fgreater(g+h, bound))
185  {
186  UpdateNextBound(bound, g+h);
187  return h;
188  }
189  }
190  }
191  return h;
192 }
193 
194 template <class state, class action, bool verbose>
196  action forbiddenAction, state &currState,
197  std::vector<action> &thePath, double bound, double g,
198  double maxH, double parentH)
199 {
200  double h = heuristic->HCost(currState, goal);//, parentH); // TODO: restore code that uses parent h-cost
201  parentH = h;
202  // path max
203  if (usePathMax && fless(h, maxH))
204  h = maxH;
205  if (fgreater(g+h, bound))
206  {
207  UpdateNextBound(bound, g+h);
208  //printf("Stopping at (%d, %d). g=%f h=%f\n", currState>>16, currState&0xFFFF, g, h);
209  return h;
210  }
211  // must do this after we check the f-cost bound
212  if (env->GoalTest(currState, goal))
213  return -1; // found goal
214 
215  std::vector<action> &actions = *actCache.getItem();
216  env->GetActions(currState, actions);
217  nodesTouched += actions.size();
218  nodesExpanded++;
219  gCostHistogram[g]++;
220  int depth = (int)thePath.size();
221 #ifdef t
222  func(currState, depth);
223 #endif
224 
225  for (unsigned int x = 0; x < actions.size(); x++)
226  {
227  if ((depth != 0) && (actions[x] == forbiddenAction))
228  continue;
229 
230  thePath.push_back(actions[x]);
231  double edgeCost = env->GCost(currState, actions[x]);
232  env->ApplyAction(currState, actions[x]);
233  action a = actions[x];
234  env->InvertAction(a);
235 
236  double childH = DoIteration(env, a, currState, thePath, bound,
237  g+edgeCost, maxH - edgeCost, parentH);
238  env->UndoAction(currState, actions[x]);
239  if (fequal(childH, -1)) // found goal
240  {
241  actCache.returnItem(&actions);
242  return -1;
243  }
244 
245  thePath.pop_back();
246 
247  // pathmax
248  if (usePathMax && fgreater(childH-edgeCost, h))
249  {
250  // nodeTable[currState] = g;//+h
251  h = childH-edgeCost;
252  if (fgreater(g+h, bound))
253  {
254  UpdateNextBound(bound, g+h);
255  actCache.returnItem(&actions);
256  return h;
257  }
258  }
259  }
260  actCache.returnItem(&actions);
261  return h;
262 }
263 
264 
265 template <class state, class action, bool verbose>
266 void IDAStar<state, action, verbose>::UpdateNextBound(double currBound, double fCost)
267 {
268  if (!fgreater(nextBound, currBound))
269  {
270  nextBound = fCost;
271  //printf("Updating next bound to %f\n", nextBound);
272  }
273  else if (fgreater(fCost, currBound) && fless(fCost, nextBound))
274  {
275  nextBound = fCost;
276  //printf("Updating next bound to %f\n", nextBound);
277  }
278 }
279 
280 
281 #endif
IDAStar::SetHeuristic
void SetHeuristic(Heuristic< state > *heur)
Definition: IDAStar.h:39
IDAStar::gCostHistogram
std::vector< uint64_t > gCostHistogram
Definition: IDAStar.h:76
Heuristic
Definition: Heuristic.h:30
SearchEnvironment::InvertAction
virtual bool InvertAction(action &a) const =0
IDAStar::nodesExpanded
unsigned long long nodesExpanded
Definition: IDAStar.h:41
SearchEnvironment::UndoAction
virtual void UndoAction(state &s, action a) const
Definition: SearchEnvironment.h:40
FPUtil.h
vectorCache.h
SearchEnvironment::GCost
virtual double GCost(const state &node1, const state &node2) const =0
NodeHashTable
std::unordered_map< uint64_t, double > NodeHashTable
Definition: IDAStar.h:23
IDAStar::goal
state goal
Definition: IDAStar.h:68
SearchEnvironment::GetActions
virtual void GetActions(const state &nodeID, std::vector< action > &actions) const =0
IDAStar::useHashTable
bool useHashTable
Definition: IDAStar.h:72
IDAStar
Definition: IDAStar.h:26
IDAStar::usePathMax
bool usePathMax
Definition: IDAStar.h:71
IDAStar::ResetNodeCount
void ResetNodeCount()
Definition: IDAStar.h:37
IDAStar::GetPath
void GetPath(SearchEnvironment< state, action > *env, state from, state to, std::vector< state > &thePath)
Definition: IDAStar.h:85
IDAStar::nextBound
double nextBound
Definition: IDAStar.h:69
verbose
const static int verbose
Definition: ClusterAbstraction.cpp:81
fless
bool fless(double a, double b)
Definition: FPUtil.h:28
IDAStar::heuristic
Heuristic< state > * heuristic
Definition: IDAStar.h:75
IDAStar::nodesTouched
unsigned long long nodesTouched
Definition: IDAStar.h:41
IDAStar::GetNodesExpanded
uint64_t GetNodesExpanded()
Definition: IDAStar.h:35
IDAStar::actCache
vectorCache< action > actCache
Definition: IDAStar.h:73
SearchEnvironment::GetSuccessors
virtual void GetSuccessors(const state &nodeID, std::vector< state > &neighbors) const =0
fgreater
bool fgreater(double a, double b)
Definition: FPUtil.h:29
vectorCache< action >
IDAStar::storedHeuristic
bool storedHeuristic
Definition: IDAStar.h:74
SearchEnvironment::HCost
virtual double HCost(const state &node1, const state &node2) const =0
Heuristic value between two arbitrary nodes.
IDAStar::DoIteration
double DoIteration(SearchEnvironment< state, action > *env, state parent, state currState, std::vector< state > &thePath, double bound, double g, double maxH)
Definition: IDAStar.h:144
IDAStar::~IDAStar
virtual ~IDAStar()
Definition: IDAStar.h:29
IDAStar::IDAStar
IDAStar()
Definition: IDAStar.h:28
SearchEnvironment::ApplyAction
virtual void ApplyAction(state &s, action a) const =0
SearchEnvironment::GoalTest
virtual bool GoalTest(const state &node, const state &goal) const =0
fequal
bool fequal(double a, double b, double tolerance=TOLERANCE)
Definition: FPUtil.h:32
SearchEnvironment
Definition: SearchEnvironment.h:30
IDAStar::PrintGHistogram
void PrintGHistogram()
Definition: IDAStar.h:51
flesseq
bool flesseq(double a, double b)
Definition: FPUtil.h:30
IDAStar::SetUseBDPathMax
void SetUseBDPathMax(bool val)
Definition: IDAStar.h:38
IDAStar::UpdateNextBound
void UpdateNextBound(double currBound, double fCost)
Definition: IDAStar.h:266
SearchEnvironment.h
IDAStar::GetNodesTouched
uint64_t GetNodesTouched()
Definition: IDAStar.h:36