HOG2
CFOptimalRefinement.cpp
Go to the documentation of this file.
1 /*
2  * CFOptimalRefinement.cpp
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 5/22/07.
6  * Copyright 2007 __MyCompanyName__. All rights reserved.
7  *
8  */
9 
10 #include "CFOptimalRefinement.h"
11 #include <vector>
12 
13 using namespace CFOptimalRefinementConstants;
14 
17 {
18  g = 0;
19 }
20 
22 {
23 }
24 
26 {
27  return "CFOptimalRefinement";
28 }
29 
31 {
32  if (!InitializeSearch(aMap, from, to))
33  return 0;
34  path *p = 0;
35  while (p == 0)
36  {
37  p = DoOneSearchStep();
38  //g->Print(std::cout);
39  }
40  return p;
41 }
42 
44 {
45  if ((gStart == 0) || (gStart->GetLabelL(kOptimalFlag) == 0))
46  {
47  node *gNext = q.top().n;
48  q.pop();
49  printf("Analyzing %d next\n", gNext->GetNum());
50  std::cout << *gNext << std::endl;
51  if (gNext->GetLabelL(kInOpenList) == 1)
52  {
53  printf("Updating node %d\n", gNext->GetNum());
54  UpdateNode(gNext);
55  }
56  else { // in closed list
57  printf("Refining node %d\n", gNext->GetNum());
58  if (gNext->GetLabelL(kAbstractionLevel) > 0)
59  RefineNode(gNext);
60  }
61  }
62  if ((gStart == 0) || (gStart->GetLabelL(kOptimalFlag) == 0))
63  {
64  return 0;
65  }
66  return new path(aStart, new path(aGoal));
67 }
68 
70 {
71  gStart = 0;
72  absGraph = aMap;
73  aStart = from;
74  aGoal = to;
75  delete g;
76  g = new Graph();
77 
78  // find most abstract node in Graph
79  node *top = FindTopLevelNode(from, to, aMap);
80  if (top == 0)
81  return false;
82  node *newTop = new node("top");
83  gStart = gGoal = newTop;
84  g->AddNode(newTop);
85  SetInitialValues(newTop, top, 0);
86  q.Add(GNode(newTop));
87  return true;
88 }
89 
91 {
92  if ((one == 0) || (two == 0))
93  return 0;
94  if (aMap->GetAbstractionLevel(one) >= (int)aMap->getNumAbstractGraphs())
95  return 0;
96  if (aMap->GetAbstractionLevel(one) == (int)aMap->getNumAbstractGraphs() - 1)
97  {
98  if (one == two)
99  return one;
100  return 0;
101  }
102  node *tmp = FindTopLevelNode(aMap->GetParent(one), aMap->GetParent(two), aMap);
103  if ((tmp == 0) && (one == two))
104  return one;
105  return tmp;
106 }
107 
108 /*
109  * aRealNode is the node inside the absGraph
110  * gNewNode is the node about to be added to Graph
111  * gParent is the parent inside the Graph
112  */
113 void CFOptimalRefinement::SetInitialValues(node *gNewNode, node *aRealNode, node *gParent)
114 {
116  gNewNode->SetLabelL(kCorrespondingNode, aRealNode->GetNum());
117  if (gParent)
118  {
119  gNewNode->SetLabelF(kGCost, gParent->GetLabelF(kGCost));
120  gNewNode->SetLabelF(kHCost, gParent->GetLabelF(kHCost));
121  }
122  else {
123  gNewNode->SetLabelF(kGCost, 0.0);
124  gNewNode->SetLabelF(kHCost, 0.0);
125  }
126  gNewNode->SetLabelL(kOptimalFlag, 0);
127  gNewNode->SetLabelL(kInOpenList, 1);
128 
129  if ((gParent == gStart) && (absGraph->IsParentOf(aRealNode, aStart)))
130  {
131  std::cout << "Assigning start to " << *gNewNode << std::endl;
132  gStart = gNewNode;
133  }
134  if ((gParent == gGoal) && (absGraph->IsParentOf(aRealNode, aGoal)))
135  {
136  std::cout << "Assigning goal to " << *gNewNode << std::endl;
137  gGoal = gNewNode;
138  }
139 }
140 
142 {
143  UpdateH(gNode);
144  std::cout << "After UpdateH " << *gNode << std::endl;
145  UpdateG(gNode);
146  std::cout << "After UpdateG " << *gNode << std::endl;
147  UpdateOptH(gNode);
148  std::cout << "After UpdateOptH " << *gNode << std::endl;
149  gNode->SetLabelL(kInOpenList, 0);
150  q.Add(GNode(gNode));
151 }
152 
154 {
155  double minH = DBL_MAX;
156 
157  // update h
158  neighbor_iterator ni = gNode->getNeighborIter();
159  for (int next = gNode->nodeNeighborNext(ni); next != -1; next = gNode->nodeNeighborNext(ni))
160  {
161  node *gNeighbor = g->GetNode(next);
162  double tmpH = gNeighbor->GetLabelF(kHCost) + g->FindEdge(next, gNode->GetNum())->GetWeight();
163  if (fless(tmpH, minH))
164  minH = tmpH;
165  }
166  if (gNode->GetLabelL(kAbstractionLevel) == 0)
167  minH = std::max(minH, absGraph->h(gNode, aGoal));
168  if (fgreater(minH, gNode->GetLabelF(kHCost)) &&
169  (gNode != gGoal))
170  {
171  gNode->SetLabelF(kHCost, minH);
172  MakeNeighborsOpen(gNode);
173  }
174 }
175 
177 {
178  double minG = DBL_MAX;
179 
180  // update g
181  neighbor_iterator ni = gNode->getNeighborIter();
182  for (int next = gNode->nodeNeighborNext(ni); next != -1; next = gNode->nodeNeighborNext(ni))
183  {
184  node *gNeighbor = g->GetNode(next);
185  double tmpG = gNeighbor->GetLabelF(kGCost) + g->FindEdge(next, gNode->GetNum())->GetWeight();
186  if (fless(tmpG, minG))
187  minG = tmpG;
188  }
189  if (gNode->GetLabelL(kAbstractionLevel) == 0)
190  minG = std::max(minG, absGraph->h(gNode, aStart));
191  if (fgreater(minG, gNode->GetLabelF(kGCost)) &&
192  (gNode != gStart))
193  {
194  gNode->SetLabelF(kGCost, minG);
195  MakeNeighborsOpen(gNode);
196  }
197 }
198 
200 {
201  bool optH = false;
202  if ((gNode->GetLabelL(kAbstractionLevel) == 0) &&
203  (gNode->GetLabelL(kOptimalFlag) == 0))
204  {
205  if (gNode == gGoal)
206  {
207  optH = true;
208  }
209  else {
210  neighbor_iterator ni = gNode->getNeighborIter();
211  for (int next = gNode->nodeNeighborNext(ni); next != -1; next = gNode->nodeNeighborNext(ni))
212  {
213  node *gNeighbor = g->GetNode(next);
214  if ((gNeighbor->GetLabelL(kOptimalFlag) == 1) &&
215  (fequal(gNeighbor->GetLabelF(kHCost) + g->FindEdge(next, gNode->GetNum())->GetWeight(),
216  gNode->GetLabelF(kHCost))))
217  {
218  optH = true;
219  }
220  }
221  }
222 
223  if ((gNode->GetLabelL(kOptimalFlag) == 0) && (optH))
224  {
225  gNode->SetLabelL(kOptimalFlag, 1);
226  MakeNeighborsOpen(gNode);
227  }
228  }
229 }
230 
232 {
233  neighbor_iterator ni = gNode->getNeighborIter();
234  for (int next = gNode->nodeNeighborNext(ni); next != -1; next = gNode->nodeNeighborNext(ni))
235  {
236  node *gNeighbor = g->GetNode(next);
237  if (gNeighbor->GetLabelL(kInOpenList) == 0)
238  {
239  gNeighbor->SetLabelL(kInOpenList, 1);
240  q.DecreaseKey(GNode(gNeighbor));
241  }
242  }
243 }
244 
246 {
247  std::vector<node *> aChildren;
248  std::vector<node *> gChildren;
249  node *aNode = GetRealNode(gNode);
250  for (int x = 0; x < absGraph->GetNumChildren(aNode); x++)
251  {
252  aChildren.push_back(absGraph->GetNthChild(aNode, x));
253  }
254 
255  // first, add children to graph g
256  for (unsigned int x = 0; x < aChildren.size(); x++)
257  {
258  gChildren.push_back(new node("child"));
259  g->AddNode(gChildren[x]);
260  SetInitialValues(gChildren[x], aChildren[x], gNode);
261  q.Add(GNode(gChildren[x]));
262  }
263 
264  // first, connect children to each other
265  Graph *aGraph = absGraph->GetAbstractGraph(absGraph->GetAbstractionLevel(aChildren[0]));
266  for (unsigned int x = 0; x < gChildren.size(); x++)
267  {
268  for (unsigned int y = 0; y < gChildren.size(); y++)
269  {
270  if (x != y)
271  {
272  edge *e;
273  if ((e = aGraph->findDirectedEdge(aChildren[x]->GetNum(), aChildren[y]->GetNum())) != 0)
274  {
275  g->AddEdge(new edge(gChildren[x]->GetNum(), gChildren[y]->GetNum(), //1.0));
276  (absGraph->GetAbstractionLevel(aChildren[0])==0)?e->GetWeight():1.5));
277  }
278  }
279  }
280  }
281 
282  // check neighbors of original node
283  neighbor_iterator ni = gNode->getNeighborIter();
284  for (int next = gNode->nodeNeighborNext(ni); next != -1; next = gNode->nodeNeighborNext(ni))
285  {
286  node *gNeighbor = g->GetNode(next);
287  if (gNeighbor->GetLabelL(kAbstractionLevel) == gNode->GetLabelL(kAbstractionLevel)-1)
288  {
289  // same level
290  for (unsigned int x = 0; x < gChildren.size(); x++)
291  {
292  edge *e;
293  if ((e = aGraph->FindEdge(aChildren[x]->GetNum(), GetRealNode(gNeighbor)->GetNum())) != 0)
294  {
295  g->AddEdge(new edge(gChildren[x]->GetNum(), gNeighbor->GetNum(), //1.0));
296  (absGraph->GetAbstractionLevel(aChildren[0])==0)?e->GetWeight():1.5));
297  }
298  }
299  }
300  else if (gNeighbor->GetLabelL(kAbstractionLevel) < gNode->GetLabelL(kAbstractionLevel)-1)
301  { // neighbor is lower
302  for (unsigned int x = 0; x < aChildren.size(); x++)
303  {
304  if (ShouldAddEdge(GetRealNode(gNeighbor), aChildren[x]))
305  g->AddEdge(new edge(gChildren[x]->GetNum(), gNeighbor->GetNum(), 1.0));
306  }
307  }
308  else { // neighbor is higher
309  for (unsigned int x = 0; x < aChildren.size(); x++)
310  {
311  if (ShouldAddEdge(aChildren[x], GetRealNode(gNeighbor)))
312  g->AddEdge(new edge(gChildren[x]->GetNum(), gNeighbor->GetNum(), 1.0));
313  }
314  }
315  }
316 
317  // last thing we do!
318  g->RemoveNode(gNode);
319 }
320 
322 {
324 }
325 
326 bool CFOptimalRefinement::ShouldAddEdge(node *aLowerNode, node *aHigherNode)
327 {
328  neighbor_iterator ni = aLowerNode->getNeighborIter();
329  for (int next = aLowerNode->nodeNeighborNext(ni); next != -1; next = aLowerNode->nodeNeighborNext(ni))
330  {
331  node *aNeighbor = absGraph->GetAbstractGraph(absGraph->GetAbstractionLevel(aLowerNode))->GetNode(next);
332  if (absGraph->IsParentOf(aHigherNode, aNeighbor))
333  return true;
334  }
335  return false;
336 }
337 
339 {
340  if ((g == 0) || (g->GetNumNodes() == 0))
341  {
342  return;
343  }
344 
345  glLineWidth(3.0);
346  glBegin(GL_LINES);
347  glNormal3f(0, 1, 0);
348  edge_iterator ei = g->getEdgeIter();
349  for (edge *e = g->edgeIterNext(ei); e; e = g->edgeIterNext(ei))
350  {
351  const node *n1;
352  n1 = g->GetNode(e->getFrom());
353  if (q.peek().n == n1)
354  glColor3f(1.0, 0.0, 1.0);
355  else if (n1 == gStart)
356  glColor3f(0, 0, 1);
357  else if (n1 == gGoal)
358  glColor3f(0, 1, 0);
359  else if (n1->GetLabelL(kOptimalFlag) && n1->GetLabelL(kInOpenList))
360  glColor3f(1.0, 1.0, 0);
361  else if (n1->GetLabelL(kOptimalFlag))
362  glColor3f(0.6, 0.6, 0);
363  else if (n1->GetLabelL(kInOpenList) == 0)
364  glColor3f(0.5, 0.5, 0.5);
365  else
366  glColor3f(1, 1, 1);
367 
368  node *n = 0; assert(false); // there is a bug here, because n was always uninitialized
370  glVertex3f(rv.x, rv.y, rv.z);
371 
372  n = g->GetNode(e->getTo());
373  if (q.peek().n == n)
374  glColor3f(1.0, 0.0, 1.0);
375  else if (n == gStart)
376  glColor3f(0, 0, 1);
377  else if (n == gGoal)
378  glColor3f(0, 1, 0);
379  else if (n->GetLabelL(kOptimalFlag) && n->GetLabelL(kInOpenList))
380  glColor3f(1.0, 1.0, 0);
381  else if (n->GetLabelL(kOptimalFlag))
382  glColor3f(0.6, 0.6, 0);
383  else if (n->GetLabelL(kInOpenList) == 0)
384  glColor3f(0.5, 0.5, 0.5);
385  else
386  glColor3f(1, 1, 1);
387  rv = absGraph->GetNodeLoc(GetRealNode(n));
388 
389  glVertex3f(rv.x, rv.y, rv.z);
390  }
391 
392  glEnd();
393  glLineWidth(1.0);
394 
395 }
396 
Graph::AddNode
int AddNode(node *)
Definition: Graph.cpp:136
GraphAbstraction
A generic class for basic operations on Graph abstractions.
Definition: GraphAbstraction.h:63
node::SetLabelL
void SetLabelL(unsigned int index, long val) const
Definition: Graph.cpp:702
edge::GetWeight
double GetWeight()
Definition: Graph.h:140
CFOptimalRefinement::q
PQueue q
Definition: CFOptimalRefinement.h:109
node::SetLabelF
void SetLabelF(unsigned int index, double val) const
Definition: Graph.cpp:687
CFOptimalRefinementConstants
Definition: CFOptimalRefinement.h:21
Graph::RemoveNode
node * RemoveNode(node *, unsigned int &)
Definition: Graph.cpp:356
CFOptimalRefinement::RefineNode
void RefineNode(node *gNode)
Definition: CFOptimalRefinement.cpp:245
Graph::FindEdge
edge * FindEdge(unsigned int from, unsigned int to)
Finds an edge between nodes with ids from and to, no matter which direction.
Definition: Graph.cpp:230
recVec
A generic vector (essentially the same as a point, but offers normalization)
Definition: GLUtil.h:78
neighbor_iterator
unsigned int neighbor_iterator
Definition: Graph.h:34
GraphAbstraction::GetAbstractGraph
Graph * GetAbstractGraph(int level)
return the abstract Graph at the given level
Definition: GraphAbstraction.h:74
recVec::z
GLdouble z
Definition: GLUtil.h:98
CFOptimalRefinement::UpdateH
void UpdateH(node *gNode)
Definition: CFOptimalRefinement.cpp:153
CFOptimalRefinement::GetPath
virtual path * GetPath(GraphAbstraction *aMap, node *from, node *to, reservationProvider *rp=0)
Definition: CFOptimalRefinement.cpp:30
OpenClosedList::DecreaseKey
void DecreaseKey(OBJ val)
Indicate that the key for a particular object has decreased.
Definition: OpenClosedList.h:96
CFOptimalRefinement::aGoal
node * aGoal
Definition: CFOptimalRefinement.h:110
Graph::AddEdge
void AddEdge(edge *)
Definition: Graph.cpp:170
CFOptimalRefinement::UpdateNode
void UpdateNode(node *gNode)
Definition: CFOptimalRefinement.cpp:141
CFOptimalRefinement::gStart
node * gStart
Definition: CFOptimalRefinement.h:111
edge_iterator
std::vector< edge * >::const_iterator edge_iterator
Definition: Graph.h:30
OpenClosedList::top
OBJ top()
Definition: OpenClosedList.h:39
GraphAbstraction::GetNthChild
node * GetNthChild(node *which, int n)
Definition: GraphAbstraction.h:88
Graph
A generic Graph class.
Definition: Graph.h:66
Graph::GetNode
node * GetNode(unsigned long num)
Definition: Graph.cpp:152
CFOptimalRefinementConstants::kHCost
@ kHCost
Definition: CFOptimalRefinement.h:28
Graph::edgeIterNext
edge * edgeIterNext(edge_iterator &) const
Definition: Graph.cpp:320
CFOptimalRefinement::InitializeSearch
bool InitializeSearch(GraphAbstraction *aMap, node *from, node *to)
Definition: CFOptimalRefinement.cpp:69
CFOptimalRefinement.h
CFOptimalRefinement::MakeNeighborsOpen
void MakeNeighborsOpen(node *gNode)
Definition: CFOptimalRefinement.cpp:231
GraphAbstraction::GetAbstractionLevel
long GetAbstractionLevel(node *which)
Definition: GraphAbstraction.h:92
GraphAbstraction::h
virtual double h(node *a, node *b)=0
heuristic cost between any two nodes
CFOptimalRefinement::DoOneSearchStep
path * DoOneSearchStep()
Definition: CFOptimalRefinement.cpp:43
Graph::getEdgeIter
edge_iterator getEdgeIter() const
Definition: Graph.cpp:315
CFOptimalRefinement::SetInitialValues
void SetInitialValues(node *gNewNode, node *aRealNode, node *gParent)
Definition: CFOptimalRefinement.cpp:113
OpenClosedList::Add
void Add(OBJ val)
Add object into OpenClosedList.
Definition: OpenClosedList.h:77
fless
bool fless(double a, double b)
Definition: FPUtil.h:28
GraphAbstraction::GetNumChildren
long GetNumChildren(node *which)
Definition: GraphAbstraction.h:87
CFOptimalRefinement::GetName
virtual const char * GetName()
Definition: CFOptimalRefinement.cpp:25
GraphAbstractionConstants::kAbstractionLevel
@ kAbstractionLevel
Definition: GraphAbstraction.h:25
OpenClosedList::pop
void pop()
Definition: OpenClosedList.h:37
fgreater
bool fgreater(double a, double b)
Definition: FPUtil.h:29
max
#define max(a, b)
Definition: MinimalSectorAbstraction.cpp:40
Graph::GetNumNodes
int GetNumNodes()
Definition: Graph.cpp:403
CFOptimalRefinementConstants::kGCost
@ kGCost
Definition: CFOptimalRefinement.h:27
CFOptimalRefinementConstants::kCorrespondingNode
@ kCorrespondingNode
Definition: CFOptimalRefinement.h:26
node::nodeNeighborNext
int nodeNeighborNext(neighbor_iterator &) const
Definition: Graph.cpp:807
CFOptimalRefinementConstants::GNode
Definition: CFOptimalRefinement.h:33
CFOptimalRefinementConstants::kInOpenList
@ kInOpenList
Definition: CFOptimalRefinement.h:30
CFOptimalRefinement::UpdateOptH
void UpdateOptH(node *gNode)
Definition: CFOptimalRefinement.cpp:199
CFOptimalRefinement::UpdateG
void UpdateG(node *gNode)
Definition: CFOptimalRefinement.cpp:176
GraphAbstraction::getNumAbstractGraphs
unsigned int getNumAbstractGraphs()
return the total number of graphs in the hierarchy
Definition: GraphAbstraction.h:76
path
std::vector< xyLoc > path
Definition: Sample.cpp:43
CFOptimalRefinement::ShouldAddEdge
bool ShouldAddEdge(node *aLowerNode, node *aHigherNode)
Definition: CFOptimalRefinement.cpp:326
CFOptimalRefinement::gGoal
node * gGoal
Definition: CFOptimalRefinement.h:111
node::GetLabelF
double GetLabelF(unsigned int index) const
Definition: Graph.h:215
node::GetNum
unsigned int GetNum() const
Definition: Graph.h:176
reservationProvider
Definition: ReservationProvider.h:33
SearchAlgorithm
A generic algorithm which can be used for pathfinding.
Definition: SearchAlgorithm.h:25
CFOptimalRefinement::~CFOptimalRefinement
virtual ~CFOptimalRefinement()
Definition: CFOptimalRefinement.cpp:21
CFOptimalRefinement::g
Graph * g
Definition: CFOptimalRefinement.h:113
GraphAbstraction::IsParentOf
bool IsParentOf(node *parent, node *child)
return true if the first node is a parent of or is equal two the second node
Definition: GraphAbstraction.cpp:78
GraphAbstraction::GetNodeLoc
virtual recVec GetNodeLoc(node *) const
Definition: GraphAbstraction.h:120
node::GetLabelL
long GetLabelL(unsigned int index) const
Definition: Graph.h:220
path
A linked list of nodes which form a continuous path.
Definition: Path.h:20
node::getNeighborIter
neighbor_iterator getNeighborIter() const
Definition: Graph.cpp:802
CFOptimalRefinement::absGraph
GraphAbstraction * absGraph
Definition: CFOptimalRefinement.h:112
recVec::y
GLdouble y
Definition: GLUtil.h:98
Graph::findDirectedEdge
edge * findDirectedEdge(unsigned int from, unsigned int to)
Definition: Graph.cpp:189
fequal
bool fequal(double a, double b, double tolerance=TOLERANCE)
Definition: FPUtil.h:32
GraphAbstraction::GetParent
node * GetParent(node *which)
Definition: GraphAbstraction.h:86
CFOptimalRefinement::FindTopLevelNode
node * FindTopLevelNode(node *one, node *two, GraphAbstraction *aMap)
Definition: CFOptimalRefinement.cpp:90
CFOptimalRefinement::CFOptimalRefinement
CFOptimalRefinement()
Definition: CFOptimalRefinement.cpp:15
recVec::x
GLdouble x
Definition: GLUtil.h:98
OpenClosedList::peek
const OBJ peek() const
Definition: OpenClosedList.h:38
CFOptimalRefinement::OpenGLDraw
void OpenGLDraw() const
Definition: CFOptimalRefinement.cpp:338
CFOptimalRefinement::GetRealNode
node * GetRealNode(node *gNode) const
Definition: CFOptimalRefinement.cpp:321
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
CFOptimalRefinement::aStart
node * aStart
Definition: CFOptimalRefinement.h:110
CFOptimalRefinementConstants::kOptimalFlag
@ kOptimalFlag
Definition: CFOptimalRefinement.h:29
edge
Edge class for connections between node in a Graph.
Definition: Graph.h:129
CFOptimalRefinementConstants::GNode::n
node * n
Definition: CFOptimalRefinement.h:36