HOG2
HeuristicLearningMeasure.h
Go to the documentation of this file.
1 /*
2  * HeuristicLearningMeasure.h
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 10/5/09.
6  * Copyright 2009 NS Software. All rights reserved.
7  *
8  */
9 
10 #ifndef HEURISTICLEARNINGMEASURE_H
11 #define HEURISTICLEARNINGMEASURE_H
12 
13 #include "SearchEnvironment.h"
14 #include <unordered_map>
15 #include "TemplateAStar.h"
16 #include <iostream>
17 #include <queue>
18 
19 template <class state>
20 class stateData {
21 public:
23  state theState;
26 };
27 
28 template <class state>
30 {
31 public:
32  bool operator() (const stateData<state> &lhs, const stateData<state> &rhs) const
33  {
34  return (lhs.learnedHeuristic < rhs.learnedHeuristic);
35  }
36 };
37 
38 struct HashDouble { // 2 digits accuracy
39  size_t operator()(const double &x) const
40  { return (size_t)(x*100); }
41 };
42 
43 class sVal {
44  public:
45  sVal() :count(0) {}
46  sVal(double v) :diff(v), count(0) {}
47  void increase() {count++;}
48  double diff; int count;
49 };
50 
51 template <class state, class action, class environment>
53 public:
54  double MeasureDifficultly(environment *env, const state &start, const state &goal)
55  {
56  learnData.clear();
57  queue.clear();
58  BuildExactDistances(env, start, goal);
59  ComputeRequiredLearning(env, start, goal);
60  std::cout << "Intermediate learning: " << SumLearningRequired() <<
61  " over " << learnData.size() << " states." << std::endl;
62  ComputeConsistencyLearning(env, goal);
63  std::cout << "Final learning: " << SumLearningRequired() << std::endl;
64  return SumLearningRequired();
65  }
66 
68  {
69  typedef std::unordered_map<double, sVal, HashDouble> HistogramData;
70  HistogramData histogram;
71  for (typename EnvironmentData::const_iterator it = learnData.begin(); it != learnData.end(); it++)
72  {
73  double diff = (*it).second.learnedHeuristic - (*it).second.initialHeuristic;
74  histogram[diff].increase();
75  histogram[diff].diff = diff;
76  }
77  for (typename HistogramData::const_iterator it = histogram.begin(); it != histogram.end(); it++)
78  {
79  printf("Histogram:\t%f\t%d\n", (*it).second.diff, (*it).second.count);
80  }
81  }
82 
83  void OpenGLDraw(environment *env) const
84  {
85  double maxLearning = 0;
86  for (typename EnvironmentData::const_iterator it = learnData.begin(); it != learnData.end(); it++)
87  {
88  double cnt = (*it).second.learnedHeuristic - (*it).second.initialHeuristic;
89  if (cnt > maxLearning)
90  maxLearning = cnt;
91  }
92 
93  for (typename EnvironmentData::const_iterator it = learnData.begin(); it != learnData.end(); it++)
94  {
95  double r = (*it).second.learnedHeuristic - (*it).second.initialHeuristic;
96  if (r > 0)
97  {
98  env->SetColor(0.5+0.5*r/maxLearning, 0, 0, 0.1+0.8*r/maxLearning);
99  env->OpenGLDraw((*it).second.theState);
100  }
101  }
102 
103  }
104 
105 private:
106  typedef std::unordered_map<uint64_t, stateData<state>, Hash64 > EnvironmentData;
107 
109  {
110  double sum = 0;
111  for (typename EnvironmentData::const_iterator it = learnData.begin(); it != learnData.end(); it++)
112  {
113 // std::cout << "State " << (*it).second.theState << " initial heuristic: " << (*it).second.initialHeuristic <<
114 // " learned: " << (*it).second.learnedHeuristic <<
115 // " diff: " << (*it).second.learnedHeuristic - (*it).second.initialHeuristic << std::endl;
116  sum += (*it).second.learnedHeuristic - (*it).second.initialHeuristic;
117  }
118  return sum;
119  }
120 
121  void BuildExactDistances(environment *env, const state &start, const state &goal)
122  {
123  std::vector<state> thePath;
124 
126  astarStart.InitializeSearch(env, start, goal, thePath);
127  //astarStart.GetPath(env, start, goal, path);
128 
130  astarGoal.InitializeSearch(env, goal, start, thePath);
131  //astarGoal.GetPath(env, goal, start, path);
132  }
133 
134  double LookupGCost(state &s)
135  {
136  std::vector<state> thePath;
137  double cost;
138  while (astarStart.GetClosedListGCost(s, cost) == false)
139  {
140  for (unsigned int x = 0; x < 20; x++)
142  }
143  return cost;
144  }
145 
146  double LookupHCost(const state &s)
147  {
148  std::vector<state> thePath;
149  double cost;
150  while (astarGoal.GetClosedListGCost(s, cost) == false)
151  {
152  for (unsigned int x = 0; x < 20; x++)
153  astarGoal.DoSingleSearchStep(thePath);
154  }
155  return cost;
156  }
157 
158  void ComputeRequiredLearning(environment *env, const state &start, const state &goal)
159  {
160  // 1. find the optimal cost
161  // 2. find all nodes with optimal cost, update & put in list
162  // 3. do BPMX stuff?
163 
164  double optimalCost = LookupHCost(start);
165 
166  std::vector<state> tempQueue;
167  std::vector<state> succ;
168  tempQueue.push_back(start);
169 
170 // learnData[env->GetStateHash(start)].theState = start;
171 // learnData[env->GetStateHash(start)].learnedHeuristic = optimalCost;
172 // learnData[env->GetStateHash(start)].initialHeuristic = env->HCost(start, goal);
173 
174  // add optimal path and neighbors to data structure
175  while (tempQueue.size() > 0)
176  {
177  state s = tempQueue.back();
178  tempQueue.pop_back();
179 
180  double gCost;
181  double hCost;
182 
183  gCost = LookupGCost(s);
184  hCost = LookupHCost(s);
185 // std::cout << s << " has g: " << gCost << " h:" << hCost << std::endl;
186 // if (!astarGoal.GetClosedListGCost(s, hCost))
187 // std::cout << "Didn't find: " << s << std::endl;
188 // if (!astarStart.GetClosedListGCost(s, gCost))
189 // std::cout << "Didn't find: " << s << std::endl;
190 
191  // seen before
192  if (!fequal(learnData[env->GetStateHash(s)].learnedHeuristic, -1))
193  continue;
194 
195  learnData[env->GetStateHash(s)].theState = s;
196  learnData[env->GetStateHash(s)].learnedHeuristic = hCost;
197  learnData[env->GetStateHash(s)].initialHeuristic = env->HCost(s, goal);
198 
199  if (fequal(hCost+gCost, optimalCost))
200  {
201  env->GetSuccessors(s, succ);
202  for (unsigned int y = 0; y < succ.size(); y++)
203  tempQueue.push_back(succ[y]);
204  //std::cout << "*";
205  }
206  //std::cout << s << " has distance cost " << hCost << " and h-cost " << env->HCost(s, goal) << std::endl;
207  }
208 
209  // clear out memory used by A* searches
211  astarGoal = clear;
212  astarStart = clear;
213  }
214 
215  void ComputeConsistencyLearning(environment *env, const state &goal)
216  {
217  typedef std::priority_queue<stateData<state>,std::vector<stateData<state> >,compareStateData<state> > pQueue;
218 
219  pQueue q;
220 
221  for (typename EnvironmentData::const_iterator it = learnData.begin(); it != learnData.end(); it++)
222  {
223  q.push((*it).second);
224  }
225 
226  std::vector<state> succ;
227  double learning = 0;
228 // int cnt = 0;
229  while (q.size() > 0)
230  {
231 // if (((cnt++)%1000) == 0)
232 // std::cout << cnt << "\t" << q.size() << "\t" << learning << std::endl;
233  state s = q.top().theState;
234  q.pop();
235 // std::cout << s << " " << learnData[env->GetStateHash(s)].learnedHeuristic << std::endl;
236  env->GetSuccessors(s, succ);
237  for (unsigned int x = 0; x < succ.size(); x++)
238  {
239  double edgeCost = env->GCost(s, succ[x]);
240 
241  if (fgreater(learnData[env->GetStateHash(s)].learnedHeuristic-edgeCost,
242  env->HCost(succ[x], goal)))
243  {
244  // only store if we can update the default heuristic.
245  if (learnData[env->GetStateHash(succ[x])].learnedHeuristic == -1)
246  {
247  learnData[env->GetStateHash(succ[x])].initialHeuristic = env->HCost(succ[x], goal);
248  learnData[env->GetStateHash(succ[x])].learnedHeuristic = env->HCost(succ[x], goal);
249  learnData[env->GetStateHash(succ[x])].theState = succ[x];
250  }
251 
252  if (learnData[env->GetStateHash(s)].learnedHeuristic-edgeCost-learnData[env->GetStateHash(succ[x])].learnedHeuristic > 0)
253  {
254  learning += learnData[env->GetStateHash(s)].learnedHeuristic-edgeCost-learnData[env->GetStateHash(succ[x])].learnedHeuristic;
255  learnData[env->GetStateHash(succ[x])].learnedHeuristic = learnData[env->GetStateHash(s)].learnedHeuristic-edgeCost;
256  q.push(learnData[env->GetStateHash(succ[x])]);
257  }
258  }
259  }
260  }
261 
262 // std::vector<state> succ;
263 // double learning = 1;
264 // while (learning > 0)
265 // {
266 // learning = 0;
267 // for (typename EnvironmentData::const_iterator it = learnData.begin(); it != learnData.end(); it++)
268 // {
269 // state s = (*it).second.theState;
270 // env->GetSuccessors(s, succ);
272 // for (unsigned int x = 0; x < succ.size(); x++)
273 // {
275 //
276 // double edgeCost = env->GCost(s, succ[x]);
277 //
278 // if (fgreater(learnData[env->GetStateHash(s)].learnedHeuristic-edgeCost,
279 // env->HCost(succ[x], goal)))
280 // {
281 // // only store if we can update the default heuristic.
282 // if (learnData[env->GetStateHash(succ[x])].learnedHeuristic == -1)
283 // {
284 // learnData[env->GetStateHash(succ[x])].initialHeuristic = env->HCost(succ[x], goal);
285 // learnData[env->GetStateHash(succ[x])].learnedHeuristic = env->HCost(succ[x], goal);
286 // learnData[env->GetStateHash(succ[x])].theState = succ[x];
287 // }
291 // if (learnData[env->GetStateHash(s)].learnedHeuristic-edgeCost-learnData[env->GetStateHash(succ[x])].learnedHeuristic > 0)
292 // {
293 // learning += learnData[env->GetStateHash(s)].learnedHeuristic-edgeCost-learnData[env->GetStateHash(succ[x])].learnedHeuristic;
294 // learnData[env->GetStateHash(succ[x])].learnedHeuristic = learnData[env->GetStateHash(s)].learnedHeuristic-edgeCost;
295 // }
296 // }
297 // }
298 // }
299 // std::cout << "Learned " << learning << " over " << learnData.size() << " states." << std::endl;
300 // }
301  std::cout << "Learned on " << learnData.size() << " states." << std::endl;
302  }
303 
304 
308  std::vector<state> queue;
309  // hash table for all states containing initial heuristic, learned heuristic & optimal distance
310  //
311 };
312 
313 #endif
stateData::theState
state theState
Definition: HeuristicLearningMeasure.h:23
TemplateAStar::SetStopAfterGoal
void SetStopAfterGoal(bool val)
Definition: TemplateAStar.h:139
stateData::learnedHeuristic
double learnedHeuristic
Definition: HeuristicLearningMeasure.h:25
HeuristicLearningMeasure::ComputeConsistencyLearning
void ComputeConsistencyLearning(environment *env, const state &goal)
Definition: HeuristicLearningMeasure.h:215
sVal
Definition: HeuristicLearningMeasure.h:43
HeuristicLearningMeasure::LookupHCost
double LookupHCost(const state &s)
Definition: HeuristicLearningMeasure.h:146
HeuristicLearningMeasure::SumLearningRequired
double SumLearningRequired()
Definition: HeuristicLearningMeasure.h:108
HeuristicLearningMeasure::astarStart
TemplateAStar< state, action, environment > astarStart
Definition: HeuristicLearningMeasure.h:306
HeuristicLearningMeasure::OpenGLDraw
void OpenGLDraw(environment *env) const
Definition: HeuristicLearningMeasure.h:83
sVal::diff
double diff
Definition: HeuristicLearningMeasure.h:48
HeuristicLearningMeasure::EnvironmentData
std::unordered_map< uint64_t, stateData< state >, Hash64 > EnvironmentData
Definition: HeuristicLearningMeasure.h:106
sVal::increase
void increase()
Definition: HeuristicLearningMeasure.h:47
HeuristicLearningMeasure::LookupGCost
double LookupGCost(state &s)
Definition: HeuristicLearningMeasure.h:134
Hash64
Definition: SearchEnvironment.h:23
sVal::sVal
sVal()
Definition: HeuristicLearningMeasure.h:45
TemplateAStar< state, action, environment >
HeuristicLearningMeasure::ShowHistogram
void ShowHistogram()
Definition: HeuristicLearningMeasure.h:67
compareStateData::operator()
bool operator()(const stateData< state > &lhs, const stateData< state > &rhs) const
Definition: HeuristicLearningMeasure.h:32
TemplateAStar.h
HashDouble
Definition: HeuristicLearningMeasure.h:38
compareStateData
Definition: HeuristicLearningMeasure.h:29
HeuristicLearningMeasure
Definition: HeuristicLearningMeasure.h:52
sVal::count
int count
Definition: HeuristicLearningMeasure.h:48
sVal::sVal
sVal(double v)
Definition: HeuristicLearningMeasure.h:46
fgreater
bool fgreater(double a, double b)
Definition: FPUtil.h:29
HeuristicLearningMeasure::learnData
EnvironmentData learnData
Definition: HeuristicLearningMeasure.h:305
TemplateAStar::InitializeSearch
bool InitializeSearch(environment *env, const state &from, const state &to, std::vector< state > &thePath)
Initialize the A* search.
Definition: TemplateAStar.h:257
TemplateAStar::GetClosedListGCost
bool GetClosedListGCost(const state &val, double &gCost) const
Get state from the closed list.
Definition: TemplateAStar.h:634
HashDouble::operator()
size_t operator()(const double &x) const
Definition: HeuristicLearningMeasure.h:39
HeuristicLearningMeasure::queue
std::vector< state > queue
Definition: HeuristicLearningMeasure.h:308
stateData::stateData
stateData()
Definition: HeuristicLearningMeasure.h:22
HeuristicLearningMeasure::MeasureDifficultly
double MeasureDifficultly(environment *env, const state &start, const state &goal)
Definition: HeuristicLearningMeasure.h:54
HeuristicLearningMeasure::ComputeRequiredLearning
void ComputeRequiredLearning(environment *env, const state &start, const state &goal)
Definition: HeuristicLearningMeasure.h:158
fequal
bool fequal(double a, double b, double tolerance=TOLERANCE)
Definition: FPUtil.h:32
stateData
Definition: HeuristicLearningMeasure.h:20
TemplateAStar::DoSingleSearchStep
bool DoSingleSearchStep(std::vector< state > &thePath)
Expand a single node.
Definition: TemplateAStar.h:314
HeuristicLearningMeasure::astarGoal
TemplateAStar< state, action, environment > astarGoal
Definition: HeuristicLearningMeasure.h:307
HeuristicLearningMeasure::BuildExactDistances
void BuildExactDistances(environment *env, const state &start, const state &goal)
Definition: HeuristicLearningMeasure.h:121
SearchEnvironment.h
stateData::initialHeuristic
double initialHeuristic
Definition: HeuristicLearningMeasure.h:24