HOG2
MPLRTAStar.h
Go to the documentation of this file.
1 //
2 // MPLRTAStar.h
3 // hog2 glut
4 //
5 // Created by Nathan Sturtevant on 2/28/12.
6 // Copyright (c) 2012 University of Denver. All rights reserved.
7 //
8 
9 #ifndef hog2_glut_MPLRTAStar_h
10 #define hog2_glut_MPLRTAStar_h
11 
12 #include "LearningAlgorithm.h"
13 #include "FPUtil.h"
14 #include <deque>
15 #include <vector>
16 //#include <unordered_map>
17 #include <unordered_map>
18 #include "Map2DEnvironment.h"
19 
20 namespace MPLRTA {
21 
22  struct learnedData {
23  learnedData() {dead = false; }
25  bool dead;
26  double theHeuristic;
27  };
28 
29  // This class defines the LRTA* algorithm
30  class MPLRTAStar : public LearningAlgorithm<xyLoc,tDirection,MapEnvironment> {
31  public:
32  MPLRTAStar(bool kill = true)
33  { fAmountLearned = 0.0f; setStart = false; doKilling = kill; }
34  virtual ~MPLRTAStar(void) { }
35 
36  void GetPath(MapEnvironment *env, const xyLoc& from, const xyLoc& to, std::vector<xyLoc> &thePath);
37  void GetPath(MapEnvironment *, const xyLoc& , const xyLoc& , std::vector<tDirection> & ) { assert(false); };
38  virtual const char *GetName() { if (doKilling) return "MPLRTAStar[kill]"; return "MPLRTAStar[]"; }
39  void SetHCost(MapEnvironment *env, const xyLoc &where, const xyLoc &to, double val)
40  {
41  heur[env->GetStateHash(where)].theHeuristic = val-env->HCost(where, to);
42  heur[env->GetStateHash(where)].theState = where;
43  }
44  double HCost(MapEnvironment *env, const xyLoc &from, const xyLoc &to) const
45  {
46  auto val = heur.find(env->GetStateHash(from));
47  if (val != heur.end())
48  {
49  return val->second.theHeuristic+env->HCost(from, to);
50  }
51  return env->HCost(from, to);
52  }
53  void Kill(MapEnvironment *env, const xyLoc &s)
54  {
55  heur[env->GetStateHash(s)].theState = s;
56  heur[env->GetStateHash(s)].dead = true;
57  }
58  bool IsDead(MapEnvironment *env, const xyLoc &from)
59  {
60  if (!doKilling) return false;
61  if (heur.find(env->GetStateHash(from)) != heur.end())
62  return heur[env->GetStateHash(from)].dead;
63  return false;
64  }
65 
66  virtual uint64_t GetNodesExpanded() const { return nodesExpanded; }
67  virtual uint64_t GetNodesTouched() const { return nodesTouched; }
68  virtual void LogFinalStats(StatCollection *s)
69  {
70  s->AddStat("TotalLearning", GetName(),fAmountLearned);
71  }
72 
73  double GetAmountLearned() { return fAmountLearned; }
74  void OpenGLDraw() const {}
75  void OpenGLDraw(const MapEnvironment *env) const;
76  private:
77  typedef std::unordered_map<uint64_t, learnedData, Hash64 > LearnedHeuristic;
78 
84  };
85 
87  void MPLRTAStar::GetPath(MapEnvironment *env, const xyLoc& from, const xyLoc& to, std::vector<xyLoc> &thePath)
88  {
89  if (setStart == false)
90  {
91  setStart = true;
92  startState = from;
93  }
94  goal = to;
95  thePath.resize(0);
96  if (from==to)
97  return;
98 
99  // Initialization -----------------------------------------------------
100  // Use the benefit rule (i.e., never decrease h[]) ?
101  static const bool benefitRule = true;
102 
103  // Initialize the variables
104  double minF = DBL_MAX;
105  double minG = 0;
106  int minC = -1;
107 
108  nodesExpanded = 0;
109  nodesTouched = 0;
110  nodesTouched++;
111 
112  // Lookahead --------------------------------------------------------------------
113  // get the current node off the open List
114  nodesExpanded++;
115 
116  // Iterate through all edges coming out of *n
117  std::vector<xyLoc> neighbors;
118  env->GetSuccessors(from, neighbors);
119  for (unsigned int x = 0; x < neighbors.size(); x++)
120  {
121  // Generate a child
122  nodesTouched++;
123 
124  if (IsDead(env, neighbors[x]))
125  continue;
126 
127 // // Check if the child's tile is occupied
128 // if (env->GetOccupancyInfo() && !env->GetOccupancyInfo()->CanMove(from, neighbors[x]))
129 // continue;
130 
131  // Compute the g values
132  double g = env->GCost(from, neighbors[x]);// e->getWeight();
133 
134  // See if the min on this level needs to be updated
135  double h = HCost(env, neighbors[x], to);
136  double f = g + h;
137 
138  if (fless(f, minF))
139  {
140  minF = f;
141  minG = g;
142  minC = (int)x;
143  }
144  // tie break the same as other algorithms
145  if (fequal(f, minF) && fgreater(g, minG))
146  {
147  minF = f;
148  minG = g;
149  minC = (int)x;
150  }
151  }
152 
153  // If there were no legitimate children (e.g., we are blocked out)
154  // then return an empty path
155  if (minC == -1)
156  return;
157 
158  // Update h ---------------------------------------------------------------------
159 
160  // Compute the new h
161  double newH = minF;
162 
163  // Compute the amount of learning
164  double oldH = HCost(env, from, to);
165  double deltaH = newH - oldH;
166 
167  // The benefit rule disallows us to make updates or account for decreases in h
168  if (benefitRule && fless(deltaH, 0.0))
169  deltaH = 0.0;
170 
171  deltaH = fabs(deltaH); // decreasing h is also learning
172 
173  // update h[from,to]
174  if (fgreater(deltaH,0.0))
175  SetHCost(env, from, to, newH);
176 
177  // Update the amount learned on this trial
178  // We do this with an if to avoid accumulating floating point errors
179  if (fgreater(deltaH,0.0))
180  fAmountLearned += deltaH;
181 
182  // test for deadness
183  tDirection dirs[] = {kN, kNW, kW, kSW, kS, kSE, kE, kNE};
184  xyLoc curr = from;
185  int changes = 0;
186  int passable = 0;
187  env->ApplyAction(curr, dirs[7]);
188  bool currPass = env->GetMap()->CanStep(curr.x, curr.y, from.x, from.y) && !IsDead(env, curr);
189  //if (currPass) passable++;
190  for (int x = 0; x < 8; x++)
191  {
192  curr = from;
193  env->ApplyAction(curr, dirs[x]);
194  bool p = env->GetMap()->CanStep(curr.x, curr.y, from.x, from.y) && !IsDead(env, curr);
195  if (p) passable++;
196  if (p == currPass)
197  continue;
198  currPass = p;
199  changes++;
200  }
201  if (passable <= 4 && changes <= 2 && !(from == startState))
202  Kill(env, from);
203 
204  // Move -------------------------------------------------------------------------
205  thePath.push_back(neighbors[minC]);
206  thePath.push_back(from);
207  return;
208  }
209 
211  {
212  double learned = 0;
213  for (LearnedHeuristic::const_iterator it = heur.begin(); it != heur.end(); it++)
214  {
215  double thisState = (*it).second.theHeuristic;
216  if (learned < thisState)
217  learned = thisState;
218  }
219  for (LearnedHeuristic::const_iterator it = heur.begin(); it != heur.end(); it++)
220  {
221  double r = (*it).second.theHeuristic;
222  if ((*it).second.dead)
223  {
224  e->SetColor(0,0,0);
225  e->OpenGLDraw((*it).second.theState);
226  }
227  else if (r > 0)
228  {
229  e->SetColor(0.5+0.5*r/learned, 0, 0, 0.1+0.8*r/learned);
230  e->OpenGLDraw((*it).second.theState);
231  }
232  }
233  }
234 
235 }
236 
237 #endif
MPLRTA::MPLRTAStar::nodesExpanded
uint64_t nodesExpanded
Definition: MPLRTAStar.h:83
kSE
@ kSE
Definition: Map2DEnvironment.h:79
MPLRTA::MPLRTAStar::OpenGLDraw
void OpenGLDraw() const
Definition: MPLRTAStar.h:74
MPLRTA::MPLRTAStar::GetName
virtual const char * GetName()
Definition: MPLRTAStar.h:38
MPLRTA::learnedData
Definition: MPLRTAStar.h:22
xyLoc::y
uint16_t y
Definition: Map2DEnvironment.h:42
MapEnvironment::GetMap
Map * GetMap() const
Definition: Map2DEnvironment.h:200
MPLRTA::MPLRTAStar::IsDead
bool IsDead(MapEnvironment *env, const xyLoc &from)
Definition: MPLRTAStar.h:58
kW
@ kW
Definition: Map2DEnvironment.h:78
MPLRTA
Definition: MPLRTAStar.h:20
MPLRTA::MPLRTAStar::goal
xyLoc goal
Definition: MPLRTAStar.h:80
LearningAlgorithm
Definition: LearningAlgorithm.h:15
MPLRTA::MPLRTAStar::GetNodesExpanded
virtual uint64_t GetNodesExpanded() const
Definition: MPLRTAStar.h:66
FPUtil.h
MPLRTA::MPLRTAStar::HCost
double HCost(MapEnvironment *env, const xyLoc &from, const xyLoc &to) const
Definition: MPLRTAStar.h:44
xyLoc
Definition: Map2DEnvironment.h:37
Map2DEnvironment.h
MPLRTA::MPLRTAStar::SetHCost
void SetHCost(MapEnvironment *env, const xyLoc &where, const xyLoc &to, double val)
Definition: MPLRTAStar.h:39
MapEnvironment::GCost
virtual double GCost(const xyLoc &node1, const xyLoc &node2) const
Definition: Map2DEnvironment.cpp:507
MPLRTA::MPLRTAStar::GetPath
void GetPath(MapEnvironment *, const xyLoc &, const xyLoc &, std::vector< tDirection > &)
Definition: MPLRTAStar.h:37
MapEnvironment::OpenGLDraw
virtual void OpenGLDraw() const
Definition: Map2DEnvironment.cpp:552
xyLoc::x
uint16_t x
Definition: Map2DEnvironment.h:41
MPLRTA::MPLRTAStar::fAmountLearned
double fAmountLearned
Definition: MPLRTAStar.h:82
MapEnvironment::ApplyAction
virtual void ApplyAction(xyLoc &s, tDirection dir) const
Definition: Map2DEnvironment.cpp:432
SearchEnvironment::SetColor
virtual void SetColor(const rgbColor &r) const
Definition: SearchEnvironment.h:102
MPLRTA::MPLRTAStar::GetAmountLearned
double GetAmountLearned()
Definition: MPLRTAStar.h:73
MapEnvironment
Definition: Map2DEnvironment.h:133
kE
@ kE
Definition: Map2DEnvironment.h:78
MPLRTA::MPLRTAStar
Definition: MPLRTAStar.h:30
MPLRTA::learnedData::theState
xyLoc theState
Definition: MPLRTAStar.h:24
MPLRTA::MPLRTAStar::GetNodesTouched
virtual uint64_t GetNodesTouched() const
Definition: MPLRTAStar.h:67
MPLRTA::learnedData::dead
bool dead
Definition: MPLRTAStar.h:25
fless
bool fless(double a, double b)
Definition: FPUtil.h:28
MPLRTA::MPLRTAStar::setStart
bool setStart
Definition: MPLRTAStar.h:81
MPLRTA::learnedData::learnedData
learnedData()
Definition: MPLRTAStar.h:23
tDirection
tDirection
Definition: Map2DEnvironment.h:77
MapEnvironment::HCost
virtual double HCost(const xyLoc &) const
Heuristic value between node and the stored goal.
Definition: Map2DEnvironment.h:154
fgreater
bool fgreater(double a, double b)
Definition: FPUtil.h:29
MapEnvironment::GetSuccessors
virtual void GetSuccessors(const xyLoc &nodeID, std::vector< xyLoc > &neighbors) const
Definition: Map2DEnvironment.cpp:59
kN
@ kN
Definition: Map2DEnvironment.h:78
MPLRTA::MPLRTAStar::startState
xyLoc startState
Definition: MPLRTAStar.h:80
MapEnvironment::GetStateHash
uint64_t GetStateHash(const xyLoc &node) const
Definition: Map2DEnvironment.cpp:534
StatCollection
The StatCollection class is for collecting stats across different parts of the simulation.
Definition: StatCollection.h:34
MPLRTA::MPLRTAStar::MPLRTAStar
MPLRTAStar(bool kill=true)
Definition: MPLRTAStar.h:32
Map::CanStep
bool CanStep(long x1, long y1, long x2, long y2) const
Definition: Map.cpp:1694
LearningAlgorithm.h
MPLRTA::MPLRTAStar::LearnedHeuristic
std::unordered_map< uint64_t, learnedData, Hash64 > LearnedHeuristic
Definition: MPLRTAStar.h:77
kS
@ kS
Definition: Map2DEnvironment.h:78
MPLRTA::MPLRTAStar::LogFinalStats
virtual void LogFinalStats(StatCollection *s)
Definition: MPLRTAStar.h:68
StatCollection::AddStat
void AddStat(const char *category, const char *owner, double value)
Add a new stat entry for the given category, owner and value.
Definition: StatCollection.cpp:67
kNE
@ kNE
Definition: Map2DEnvironment.h:78
MPLRTA::MPLRTAStar::Kill
void Kill(MapEnvironment *env, const xyLoc &s)
Definition: MPLRTAStar.h:53
MPLRTA::MPLRTAStar::~MPLRTAStar
virtual ~MPLRTAStar(void)
Definition: MPLRTAStar.h:34
fequal
bool fequal(double a, double b, double tolerance=TOLERANCE)
Definition: FPUtil.h:32
kSW
@ kSW
Definition: Map2DEnvironment.h:79
MPLRTA::MPLRTAStar::nodesTouched
uint64_t nodesTouched
Definition: MPLRTAStar.h:83
MPLRTA::MPLRTAStar::GetPath
void GetPath(MapEnvironment *env, const xyLoc &from, const xyLoc &to, std::vector< xyLoc > &thePath)
The core routine of MPLRTAStar – computes at most one-move path.
Definition: MPLRTAStar.h:87
MPLRTA::MPLRTAStar::doKilling
bool doKilling
Definition: MPLRTAStar.h:81
MPLRTA::MPLRTAStar::heur
LearnedHeuristic heur
Definition: MPLRTAStar.h:79
MPLRTA::learnedData::theHeuristic
double theHeuristic
Definition: MPLRTAStar.h:26
kNW
@ kNW
Definition: Map2DEnvironment.h:78