HOG2
FringeSearch.cpp
Go to the documentation of this file.
1 /*
2  * FringeSearch.cpp
3  * hog
4  *
5  * Created by Nathan Sturtevant on 1/19/07.
6  * Copyright 2007 __MyCompanyName__. All rights reserved.
7  *
8  */
9 
10 #include "FringeSearch.h"
11 #include "FPUtil.h"
12 
13 #ifndef MAXFLOAT
14 #define MAXFLOAT ((float)3.40282346638528860e+38)
15 #endif
16 
17 using namespace GraphAbstractionConstants;
18 static bool verbose = false;
19 
22 {
23  bpmx = false;
24  currList = &list1;
25  nextList = &list2;
26  hp = 0;
27 }
28 
30 {
31  initializeSearch(_aMap, from, to);
32 
33  if ((from == 0) || (to == 0) || (!aMap->Pathable(from, to)) || (from == to))
34  return 0;
35 
36  currList->push_back(from);
37  currFLimit = getHCost(from);
39  node *currOpenNode;
40  while (currList->size() > 0)
41  {
42  currOpenNode = currList->back();
43  currList->pop_back();
44  if (currOpenNode == 0)
45  {
47  continue;
48  }
49  if (verbose) printf("Expanding %d\n", currOpenNode->GetNum());
50 
51  if (fgreater(getFCost(currOpenNode), currFLimit))
52  {
53  if (verbose) printf("FCost %f above limit %f\n", getFCost(currOpenNode), currFLimit);
54  nextFLimit = min(nextFLimit, getFCost(currOpenNode));
55  nodesTouched++;
56  addToOpenList2(currOpenNode);
58  continue;
59  }
60 
61  if (currOpenNode == to)
62  break;
63 
64  addToClosedList(currOpenNode);
65  nodesExpanded++;
66 
67  edge_iterator ei = currOpenNode->getEdgeIter();
68 
69  // iterate over all the children
70  for (edge *e = currOpenNode->edgeIterNext(ei); e; e = currOpenNode->edgeIterNext(ei))
71  {
72  nodesTouched++;
73  unsigned int which;
74  if ((which = e->getFrom()) == currOpenNode->GetNum()) which = e->getTo();
75  node *neighbor = g->GetNode(which);
76  assert(neighbor != 0);
77 
79  {
80  if (verbose) printf("->Child %d on closed list\n", neighbor->GetNum());
81  updateCosts(neighbor, currOpenNode, e);
82  continue;
83  }
84  else if (onOpenList(neighbor))
85  {
86  if (verbose) printf("->Child %d on open list\n", neighbor->GetNum());
87  updateCosts(neighbor, currOpenNode, e);
88  }
89  else // not on any list
90  {
91  addCosts(neighbor, currOpenNode, e);
93  if (verbose) printf("->Child %d new to search f(%f) g(%f) h(%f)\n", neighbor->GetNum(),
95  }
96  }
98  }
99  //printf("Fringe %d nodes expanded, %d nodes touched\n", nodesExpanded, nodesTouched);
100  return extractBestPath(to);
101 }
102 
104 {
105  nodesTouched = 0;
106  nodesExpanded = 0;
107  nodesReopened = 0;
108  nodesHPropagated = 0;
109  list1.resize(0);
110  list2.resize(0);
111  closedList.resize(0);
112  costTable.resize(0);
113  aMap = aGraph;
114  goal = to;
116 
117  addCosts(from, 0, 0);
118 }
119 
121 {
122  n->key = currList->size();
123  currList->push_back(n);
124 }
125 
127 {
128  if ((n->key < currList->size()) && ((*currList)[n->key] == n))
129  return;
130  if ((n->key < nextList->size()) && ((*nextList)[n->key] == n))
131  {
132  if (verbose) printf("Moved %d to current open list\n", n->GetNum());
133  (*nextList)[n->key] = 0;
134  n->key = currList->size();
135  currList->push_back(n);
136  }
137 }
138 
140 {
141  n->key = nextList->size();
142  nextList->push_back(n);
143 }
144 
146 {
147  n->key = closedList.size();
148  closedList.push_back(n);
149 }
150 
152 {
153  if ((n->key < closedList.size()) && (closedList[n->key] == n))
154  return true;
155  return false;
156 }
157 
159 {
160  if ((n->key < list1.size()) && (list1[n->key] == n))
161  return true;
162  if ((n->key < list2.size()) && (list2[n->key] == n))
163  return true;
164  return false;
165 }
166 
168 {
169  if (n == 0)
170  return 0;
171  costs val;
172  getCosts(n, val);
173  return val.gCost+val.hCost;
174 }
175 
177 {
178  if (n == 0)
179  return 0;
180  costs val;
181  getCosts(n, val);
182  return val.gCost;
183 }
184 
186 {
187  if (n == 0)
188  return MAXFLOAT;
189  costs val;
190  getCosts(n, val);
191  return val.hCost;
192 }
193 
194 void FringeSearch::setHCost(node *n, double val)
195 {
196  unsigned long index = n->GetLabelL(kTemporaryLabel);
197  if ((index < costTable.size()) && (costTable[index].n == n))
198  {
199  costTable[index].hCost = val;
200  return;
201  }
202  printf("setHCost Error: node %d not found!\n", n->GetNum());
203  assert(false);
204 }
205 
207 {
208  unsigned long index = n->GetLabelL(kTemporaryLabel);
209  if ((index < costTable.size()) && (costTable[index].n == n))
210  {
211  val = costTable[index];
212  return;
213  }
214  printf("Error: node %d not found!\n", n->GetNum());
215  assert(false);
216 }
217 
218 void FringeSearch::addCosts(node *n, node *parent, edge *e)
219 {
220  n->markEdge(e);
221  costs val;
222  val.n = n;
223  if ((parent) && (e))
224  {
225  val.gCost = getGCost(parent)+e->GetWeight();
226  val.hCost = h(n, goal);
227  n->SetLabelL(kTemporaryLabel, costTable.size());
228  costTable.push_back(val);
229 
230  if (fgreater(getHCost(parent)-e->GetWeight(), h(n, goal)))
231  { // regular path max
232  if (verbose) printf("Doing regular path max!\n");
233  setHCost(n, getHCost(parent)-e->GetWeight());
234  }
235  if (bpmx)
236  {
237  if (fgreater(val.hCost-e->GetWeight(), getHCost(parent)))
238  { // reverse path max!
239  if (verbose) printf("-> %d h value raised from %f to %f\n", parent->GetNum(),
240  getHCost(parent), getHCost(n)-e->GetWeight());
241  setHCost(parent, getHCost(n)-e->GetWeight());
242  if (verbose) printf("Doing reverse path max!\n");
243  propagateHValues(parent, 2);
244  }
245  }
246  }
247  else {
248  val.gCost = getGCost(parent);
249  val.hCost = h(n, goal);
250  n->SetLabelL(kTemporaryLabel, costTable.size());
251  costTable.push_back(val);
252  }
253 }
254 
256 {
257  if (fgreater(getGCost(n), getGCost(parent)+e->GetWeight()))
258  {
259  n->markEdge(e);
261  if (verbose) printf("Updated g-cost of %d from %f to %f (through %d) -- (%f limit)\n", n->GetNum(),
262  val.gCost, getGCost(parent)+e->GetWeight(), parent->GetNum(), currFLimit);
263  val.gCost = getGCost(parent)+e->GetWeight();
264  propagateGValues(n);
265  // I check the nextFLimit, because we might want to update it for this node
267  }
268 }
269 
271 {
272  path *p = 0;
273  edge *e;
274  // extract best path from Graph -- each node has a single parent in the Graph which is the marked edge
275  // for visuallization purposes, an edge can be marked meaning it will be drawn in white
276  while ((e = n->getMarkedEdge()))
277  {
278  if (verbose) printf("%d <- ", n->GetNum());
279 
280  p = new path(n, p);
281 
282  e->setMarked(true);
283 
284  if (e->getFrom() == n->GetNum())
285  n = g->GetNode(e->getTo());
286  else
287  n = g->GetNode(e->getFrom());
288  }
289  p = new path(n, p);
290  if (verbose) printf("%d\n", n->GetNum());
291  return p;
292 }
293 
295 {
296  if (currList->size() == 0) // swap our lists!
297  {
298  nodeList *tmp = currList;
299  currList = nextList;
300  nextList = tmp;
303  if (verbose)
304  printf("Beginning new iteration, flimit %f, %d items in q\n",
305  currFLimit, (int)currList->size());
306  }
307 }
308 
309 // just figure out how/when to call this!
311 {
312  if (dist == 0)
313  return;
314  nodesExpanded++;
316  edge_iterator ei = n->getEdgeIter();
317 
318  // iterate over all the children
319  for (edge *e = n->edgeIterNext(ei); e; e = n->edgeIterNext(ei))
320  {
321  nodesTouched++;
322  unsigned int which;
323  if ((which = e->getFrom()) == n->GetNum()) which = e->getTo();
324  node *neighbor = g->GetNode(which);
325 
327  {
328  if (fless(getHCost(neighbor), getHCost(n)-e->GetWeight())) // do update!
329  {
330  if (verbose) printf("%d h value raised from %f to %f\n", neighbor->GetNum(),
331  getHCost(neighbor), getHCost(n)-e->GetWeight());
332  setHCost(neighbor, getHCost(n)-e->GetWeight());
333  propagateHValues(neighbor, dist-1);
334  }
335  }
336  }
337 }
338 
339 // just figure out how/when to call this!
341 {
342  if (onClosedList(n))
343  nodesReopened++;
344 
345  nodesExpanded++;
346  edge_iterator ei = n->getEdgeIter();
347  if (onOpenList(n) && (!fgreater(getFCost(n), currFLimit)))
348  moveToOpenList1(n);
349 
350  // iterate over all the children
351  for (edge *e = n->edgeIterNext(ei); e; e = n->edgeIterNext(ei))
352  {
353  nodesTouched++;
354  unsigned int which;
355  if ((which = e->getFrom()) == n->GetNum()) which = e->getTo();
356  node *neighbor = g->GetNode(which);
357 
358  if ((onOpenList(neighbor) || onClosedList(neighbor)))// && (neighbor->getMarkedEdge() == e)
359  {
360  updateCosts(neighbor, n, e);
361  }
362  }
363 }
364 
365 
366 double FringeSearch::h(node *n1, node *n2)
367 {
368  if (hp)
369  return hp->h(n1->GetNum(), n2->GetNum());
370  if ((n1->GetNum()+n2->GetNum())%2)
371  return aMap->h(n1, n2);
372  return 0;
373 }
374 
heuristicProvider::h
virtual double h(uint32_t node1, uint32_t node2)=0
FringeSearch::addToOpenList
void addToOpenList(node *n)
Definition: FringeSearch.cpp:120
GraphAbstraction
A generic class for basic operations on Graph abstractions.
Definition: GraphAbstraction.h:63
GraphAbstractionConstants
Definition: GraphAbstraction.h:22
node::SetLabelL
void SetLabelL(unsigned int index, long val) const
Definition: Graph.cpp:702
FringeSearch::FringeSearch
FringeSearch()
Definition: FringeSearch.cpp:20
edge::GetWeight
double GetWeight()
Definition: Graph.h:140
node::getMarkedEdge
edge * getMarkedEdge()
Definition: Graph.h:228
graphMove
Definition: GraphEnvironment.h:34
edge::getFrom
unsigned int getFrom() const
Definition: Graph.h:146
edge::getTo
unsigned int getTo() const
Definition: Graph.h:147
min
double min(double a, double b)
Definition: FPUtil.h:35
GraphAbstraction::GetAbstractGraph
Graph * GetAbstractGraph(int level)
return the abstract Graph at the given level
Definition: GraphAbstraction.h:74
graph_object::key
unsigned int key
Definition: Graph.h:54
FringeSearch.h
FringeSearch::propagateGValues
void propagateGValues(node *n)
Definition: FringeSearch.cpp:340
edge::setMarked
void setMarked(bool marked)
Definition: Graph.h:149
FringeSearch::initializeSearch
void initializeSearch(GraphAbstraction *aGraph, node *from, node *to)
Definition: FringeSearch.cpp:103
FringeSearch::getFCost
double getFCost(node *n)
Definition: FringeSearch.cpp:167
FringeSearch::nodesReopened
unsigned int nodesReopened
Definition: FringeSearch.h:68
edge_iterator
std::vector< edge * >::const_iterator edge_iterator
Definition: Graph.h:30
FringeSearch::nextFLimit
double nextFLimit
Definition: FringeSearch.h:67
FPUtil.h
MAXFLOAT
#define MAXFLOAT
Definition: FringeSearch.cpp:14
FringeSearch::g
Graph * g
Definition: FringeSearch.h:60
SearchAlgorithm::nodesTouched
uint32_t nodesTouched
Definition: SearchAlgorithm.h:37
Graph::GetNode
node * GetNode(unsigned long num)
Definition: Graph.cpp:152
verbose
static bool verbose
Definition: FringeSearch.cpp:18
FringeSearch::addToOpenList2
void addToOpenList2(node *n)
Definition: FringeSearch.cpp:139
costs::gCost
double gCost
Definition: FringeSearch.h:18
node::markEdge
void markEdge(edge *e)
Definition: Graph.h:227
node::getEdgeIter
edge_iterator getEdgeIter() const
Definition: Graph.cpp:749
GraphAbstraction::h
virtual double h(node *a, node *b)=0
heuristic cost between any two nodes
FringeSearch::getHCost
double getHCost(node *n)
Definition: FringeSearch.cpp:185
FringeSearch::closedList
nodeList closedList
Definition: FringeSearch.h:65
FringeSearch::addToClosedList
void addToClosedList(node *n)
Definition: FringeSearch.cpp:145
GraphAbstraction::Pathable
virtual bool Pathable(node *from, node *to)=0
is there a legal path between these 2 nodes?
FringeSearch::h
double h(node *n1, node *n2)
Definition: FringeSearch.cpp:366
costs
Definition: FringeSearch.h:15
FringeSearch::onOpenList
bool onOpenList(node *n)
Definition: FringeSearch.cpp:158
FringeSearch::GetPath
virtual path * GetPath(GraphAbstraction *aMap, node *from, node *to, reservationProvider *rp=0)
Definition: FringeSearch.cpp:29
FringeSearch::updateCosts
void updateCosts(node *n, node *parent, edge *e)
Definition: FringeSearch.cpp:255
FringeSearch::moveToOpenList1
void moveToOpenList1(node *n)
Definition: FringeSearch.cpp:126
fless
bool fless(double a, double b)
Definition: FPUtil.h:28
FringeSearch::list1
nodeList list1
Definition: FringeSearch.h:63
FringeSearch::hp
heuristicProvider * hp
Definition: FringeSearch.h:62
SearchAlgorithm::nodesExpanded
uint32_t nodesExpanded
Definition: SearchAlgorithm.h:36
FringeSearch::propagateHValues
void propagateHValues(node *n, int dist=10000)
Definition: FringeSearch.cpp:310
GraphAbstractionConstants::kAbstractionLevel
@ kAbstractionLevel
Definition: GraphAbstraction.h:25
FringeSearch::addCosts
void addCosts(node *n, node *parent, edge *e)
Definition: FringeSearch.cpp:218
FringeSearch::onClosedList
bool onClosedList(node *n)
Definition: FringeSearch.cpp:151
fgreater
bool fgreater(double a, double b)
Definition: FPUtil.h:29
FringeSearch::extractBestPath
path * extractBestPath(node *n)
Definition: FringeSearch.cpp:270
FringeSearch::nodesHPropagated
unsigned int nodesHPropagated
Definition: FringeSearch.h:68
path
std::vector< xyLoc > path
Definition: Sample.cpp:43
FringeSearch::setHCost
void setHCost(node *n, double val)
Definition: FringeSearch.cpp:194
FringeSearch::list2
nodeList list2
Definition: FringeSearch.h:63
FringeSearch::costTable
costList costTable
Definition: FringeSearch.h:66
FringeSearch::nextList
nodeList * nextList
Definition: FringeSearch.h:64
FringeSearch::aMap
GraphAbstraction * aMap
Definition: FringeSearch.h:61
node::GetNum
unsigned int GetNum() const
Definition: Graph.h:176
FringeSearch::currList
nodeList * currList
Definition: FringeSearch.h:64
FringeSearch::getGCost
double getGCost(node *n)
Definition: FringeSearch.cpp:176
GraphAbstractionConstants::kTemporaryLabel
@ kTemporaryLabel
Definition: GraphAbstraction.h:29
FringeSearch::getCosts
void getCosts(node *n, costs &val)
Definition: FringeSearch.cpp:206
reservationProvider
Definition: ReservationProvider.h:33
FringeSearch::goal
node * goal
Definition: FringeSearch.h:59
SearchAlgorithm
A generic algorithm which can be used for pathfinding.
Definition: SearchAlgorithm.h:25
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
costs::hCost
double hCost
Definition: FringeSearch.h:18
node::edgeIterNext
edge * edgeIterNext(edge_iterator &) const
Definition: Graph.cpp:754
FringeSearch::checkIteration
void checkIteration()
Definition: FringeSearch.cpp:294
FringeSearch::bpmx
bool bpmx
Definition: FringeSearch.h:69
costs::n
node * n
Definition: FringeSearch.h:17
nodeList
std::vector< node * > nodeList
Definition: FringeSearch.h:21
FringeSearch::currFLimit
double currFLimit
Definition: FringeSearch.h:67
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
edge
Edge class for connections between node in a Graph.
Definition: Graph.h:129