HOG2
AStar.cpp
Go to the documentation of this file.
1 /*
2  * $Id: aStar.cpp
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 3/22/06.
6  * Modified by Nathan Sturtevant on 02/29/20.
7  *
8  * This file is part of HOG2. See https://github.com/nathansttt/hog2 for licensing information.
9  *
10  */
11 
12 #include "AStar.h"
13 #include "float.h"
14 #include "FPUtil.h"
15 
16 using namespace GraphAbstractionConstants;
17 using namespace AStar3Util;
18 static const bool verbose = false;
19 //const int gMaxAbstraction = 0;
20 
21 const char *aStar::GetName()
22 {
23  static char name[32];
24  sprintf(name, "aStar[]");
25  return name;
26 }
27 
28 
29 //aStar::aStar(GraphAbstraction *_abstr, node *_start, node *_goal,
30 // path *corridor, int corridorWidth, int _absLevel)
32 {
33  //assert(openList.size() == 0);
34  assert(openQueue.size() == 0);
35  assert(closedList.size() == 0);
36  nodesTouched = nodesExpanded = 0;
37  abstr = aMap;
38  start = from;
39  goal = to;
40  if ((from == 0) || (to == 0) || (from == to) || (!aMap->Pathable(from, to)))
41  return 0;
42  g = abstr->GetAbstractGraph(start);
43 
44  SearchNode first(internalHeuristic(goal, start), 0, 0, start, start);
45  openQueue.Add(first);
46  //openList[start] = first;
47 
48  return getPathToNode(goal, (from->GetLabelL(kAbstractionLevel) == 0)?rp:0);
49  //printf("##Initial nodes expanded: %d, touched: %d\n", nodesExpanded, nodesTouched);
50 }
51 
52 void aStar::setCorridor(path *corridor, int width)
53 {
54  eligibleNodes.resize(0);
55  buildCorridor(corridor, width);
56 }
57 
59 {
60  node *currentOpenNode = 0;
61  while ((openQueue.size() > 0) && (currentOpenNode != target))
62  {
63  // get top of queue
64  currentOpenNode = getNextNode();
65  if (currentOpenNode == target)
66  break;
67  //assert(openList.size() == openQueue.size());
68  if (currentOpenNode == 0)
69  printf("Oh no! The current open node is NULL\n");
70  edge_iterator ei = currentOpenNode->getEdgeIter();
71 
72  // iterate over all the children
73  for (edge *e = currentOpenNode->edgeIterNext(ei); e; e = currentOpenNode->edgeIterNext(ei))
74  {
75  nodesTouched++;
76  unsigned int which;
77  if ((which = e->getFrom()) == currentOpenNode->GetNum()) which = e->getTo();
78  node *neighbor = g->GetNode(which);
79  assert(neighbor != 0);
80 
81  if (closedList.find(neighbor) != closedList.end())
82  {
83  if (verbose) { printf("skipping node %d\n", neighbor->GetNum()); }
84  continue;
85  }
86  else if (rp && (neighbor != target) && rp->nodeOccupied(neighbor))
87  {
88  if (verbose) { printf("skipping occupied node %d\n", neighbor->GetNum()); }
89  continue;
90  }
91  else if (!nodeInCorridor(neighbor))
92  {
93  if (verbose) { printf("node %d not in corridor\n", neighbor->GetNum()); }
94  }
95  else if (openQueue.IsIn(SearchNode(neighbor)))
96  //else if (openList.find(neighbor) != openList.end())
97  {
98  if (verbose) { printf("updating node %d\n", neighbor->GetNum()); }
99  updateWeight(currentOpenNode, neighbor, e);
100  //assert(openList.size() == openQueue.size());
101  }
102  else {
103  if (verbose) { printf("addinging node %d\n", neighbor->GetNum()); }
104  addToOpenList(currentOpenNode, neighbor, e);
105  //assert(openList.size() == openQueue.size());
106  }
107  }
108  }
109  if (currentOpenNode == target)
110  {
111  // if (abstr->GetAbstractionLevel(whence) == 0)
112  path *p = extractPathToStart(g, currentOpenNode);
113  closedList.clear();
114  //openList.clear();
115  openQueue.reset();
116  return p;
117  }
118  closedList.clear();
119  //openList.clear();
120  openQueue.reset();
121  return 0; // no path found!
122 }
123 
125 {
126  nodesExpanded++;
127  node *next;
128  SearchNode it = openQueue.Remove();
129  next = it.currNode;
130 // if (openList.find(next) == openList.end())
131 // {
132 // printf("Error; next node in openQueue not in openList!\n");
133 // }
134  //openList.erase(openList.find(next));
135  closedList[next] = it;
136 // if (openList.size() != openQueue.size())
137 // {
138 // printf("openList size %u, openQueue size %u\n", (unsigned int)openList.size(),
139 // (unsigned int)openQueue.size());
140 // printf("Opening node %d (f = %1.2f, g = %1.2f. [h=%1.2f])\n",
141 // next->GetNum(), it.fCost, it.gCost, abstr->h(next, goal));
142 // assert(openList.size() == openQueue.size());
143 // }
144  return next;
145 }
146 
147 void aStar::updateWeight(node *currOpenNode, node *neighbor, edge *e)
148 {
149  assert(openQueue.IsIn(SearchNode(neighbor)));
150  SearchNode prev = openQueue.find(SearchNode(neighbor));
151  //SearchNode prev = openList[neighbor];
152  SearchNode alt = closedList[currOpenNode];
153  double altCost = alt.gCost+e->GetWeight()+(prev.fCost-prev.gCost);
154  if (fgreater(prev.fCost, altCost))
155  {
156  //prev.steps = alt.steps+1;
157  prev.fCost = altCost;
158  prev.gCost = alt.gCost+e->GetWeight();
159  prev.prevNode = currOpenNode;
160  prev.e = e;
161  // reset neighbor in queue
162  //openQueue.erase(openQueue.find(neighbor));
163  //openQueue.push(prev);
164  openQueue.DecreaseKey(prev);
165 // openList[neighbor] = prev;
166  }
167 }
168 
169 void aStar::addToOpenList(node *currOpenNode, node *neighbor, edge *e)
170 {
171  SearchNode n(closedList[currOpenNode].gCost+e->GetWeight()+internalHeuristic(neighbor, goal),
172  closedList[currOpenNode].gCost+e->GetWeight(),
173  e,
174  neighbor, currOpenNode/*, closedList[currOpenNode].steps+1*/);
175  if (verbose)
176  { printf("Adding %u to openQueue, old size %u, ", neighbor->GetNum(), openQueue.size()); }
177  openQueue.Add(n);
178 
179  if (verbose)
180  {
181  printf("New size %u\n", openQueue.size());
182 // printf("Adding %u to openList, old size %u, ", (unsigned int)neighbor->GetNum(),
183 // (unsigned int)openList.size());
184  }
185 // openList[neighbor] = n;
186  if (verbose)
187  {
188 // printf("New size %u\n", (unsigned int)openList.size());
189 // if (openList.find(neighbor) == openList.end())
190 // printf("!!Hey; can't lookup the item I just inserted!\n");
191 // assert(openList.find(neighbor) != openList.end());
192  }
193 }
194 
196 {
197  path *p = 0;
198  SearchNode n = closedList[goalNode];
199  do {
200  if (n.currNode && n.prevNode)
201  _g->FindEdge(n.currNode->GetNum(), n.prevNode->GetNum())->setMarked(true);
202  p = new path(n.currNode, p);
203  n = closedList[n.prevNode];
204  } while (n.currNode != n.prevNode);
205  p = new path(n.currNode, p);
206  return p;
207 }
208 
210 {
211  printf("%u items in closed list\n", (unsigned int)closedList.size());
212 // printf("%u items in open list\n", (unsigned int)openList.size());
213  printf("%u items in open queue\n", (unsigned int)openQueue.size());
214 }
215 
217 {
218  return closedList.size()+openQueue.size();
219 }
220 
221 void aStar::buildCorridor(path *p, int windowSize)
222 {
223  // Corridor eligibleNodes;
224  for (path *t = p; t; t = t->next)
225  addNeighborsToCorridor(abstr->GetAbstractGraph(t->n), t->n, windowSize);
226 }
227 
228 void aStar::addNeighborsToCorridor(Graph *_g, node *n, int windowSize)
229 {
230  // if node is already in corridor, stop
231  // if (eligibleNodes.find(n) != eligibleNodes.end())
232  // return;
233  eligibleNodes[n] = true;
234  edge_iterator ei = n->getEdgeIter();
235 
236  // iterate over all the neighbors
237  for (edge *e = n->edgeIterNext(ei); e; e = n->edgeIterNext(ei))
238  {
239  unsigned int which;
240  if ((which = e->getFrom()) == n->GetNum()) which = e->getTo();
241 
242  node *neighbor = _g->GetNode(which);
243  if (windowSize)
244  addNeighborsToCorridor(_g, neighbor, windowSize-1);
245  else
246  eligibleNodes[neighbor] = true;
247  }
248 }
249 
251 {
252  return ((eligibleNodes.size() == 0) ||
253  (eligibleNodes.find(abstr->GetParent(n)) != eligibleNodes.end()));
254 }
255 
257 {
258  // if ((abstr->GetAbstractionLevel(from) >= gMaxAbstraction) || (abstraction == 0))
259  return abstr->h(from, to);
260  // return abstraction->getHVal(abstr->GetParent(from));
261 }
aStar::buildCorridor
void buildCorridor(path *p, int windowSize)
Definition: AStar.cpp:221
GraphAbstraction
A generic class for basic operations on Graph abstractions.
Definition: GraphAbstraction.h:63
GraphAbstractionConstants
Definition: GraphAbstraction.h:22
edge::GetWeight
double GetWeight()
Definition: Graph.h:140
AStar3Util
Definition: AStar.h:24
aStar::addNeighborsToCorridor
void addNeighborsToCorridor(Graph *g, node *n, int windowSize)
Definition: AStar.cpp:228
graphMove
Definition: GraphEnvironment.h:34
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
verbose
static const bool verbose
Definition: AStar.cpp:18
AStar3Util::SearchNode
Definition: AStar.h:26
edge::setMarked
void setMarked(bool marked)
Definition: Graph.h:149
AStar3Util::SearchNode::prevNode
node * prevNode
Definition: AStar.h:39
edge_iterator
std::vector< edge * >::const_iterator edge_iterator
Definition: Graph.h:30
FPUtil.h
width
int width
Definition: SFML_HOG.cpp:54
aStar::getMemoryUsage
int getMemoryUsage()
Definition: AStar.cpp:216
neighbor
graphMove neighbor
Definition: RoadMap.h:17
AStar3Util::SearchNode::currNode
node * currNode
Definition: AStar.h:38
Graph
A generic Graph class.
Definition: Graph.h:66
Graph::GetNode
node * GetNode(unsigned long num)
Definition: Graph.cpp:152
aStar::GetName
virtual const char * GetName()
Definition: AStar.cpp:21
node::getEdgeIter
edge_iterator getEdgeIter() const
Definition: Graph.cpp:749
GraphAbstraction::Pathable
virtual bool Pathable(node *from, node *to)=0
is there a legal path between these 2 nodes?
AStar3Util::SearchNode::e
edge * e
Definition: AStar.h:37
aStar::getNextNode
node * getNextNode()
Definition: AStar.cpp:124
GraphAbstractionConstants::kAbstractionLevel
@ kAbstractionLevel
Definition: GraphAbstraction.h:25
aStar::updateWeight
void updateWeight(node *currOpenNode, node *neighbor, edge *e)
Definition: AStar.cpp:147
aStar::internalHeuristic
double internalHeuristic(node *from, node *to)
Definition: AStar.cpp:256
aStar::printStats
void printStats()
Definition: AStar.cpp:209
fgreater
bool fgreater(double a, double b)
Definition: FPUtil.h:29
aStar::getPathToNode
path * getPathToNode(node *target, reservationProvider *rp)
Definition: AStar.cpp:58
path
std::vector< xyLoc > path
Definition: Sample.cpp:43
aStar::nodeInCorridor
bool nodeInCorridor(node *n)
Definition: AStar.cpp:250
aStar::addToOpenList
void addToOpenList(node *currOpenNode, node *neighbor, edge *e)
Definition: AStar.cpp:169
aStar::setCorridor
void setCorridor(path *corridor, int width)
Definition: AStar.cpp:52
node::GetNum
unsigned int GetNum() const
Definition: Graph.h:176
AStar3Util::SearchNode::fCost
double fCost
Definition: AStar.h:34
reservationProvider
Definition: ReservationProvider.h:33
aStar::GetPath
path * GetPath(GraphAbstraction *aMap, node *from, node *to, reservationProvider *rp=0)
Definition: AStar.cpp:31
path::next
path * next
Definition: Path.h:23
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
AStar.h
reservationProvider::nodeOccupied
virtual bool nodeOccupied(node *)=0
AStar3Util::SearchNode::gCost
double gCost
Definition: AStar.h:35
node::edgeIterNext
edge * edgeIterNext(edge_iterator &) const
Definition: Graph.cpp:754
aStar::extractPathToStart
path * extractPathToStart(Graph *g, node *n)
Definition: AStar.cpp:195
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