HOG2
PRAStar2.cpp
Go to the documentation of this file.
1 /*
2  * $Id: praStar2.cpp
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 6/23/05.
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 "PRAStar2.h"
13 #include "FPUtil.h"
14 
15 using namespace GraphAbstractionConstants;
16 static const int verbose = 0;
17 
20 {
21  partialLimit = -1;
22  expandSearchRadius = true;
24  sprintf(algName,"PRA2*(%d)", partialLimit);
25  skip = 0; //don't skip any levels
26  fixedPlanLevel = -1; //don't use a fixed plan level
27  planFromMiddle = true; //dynamically find starting level
28  numLevels = 0;
29  topLevel = -1;
30 }
31 
33 {
34  std::vector<node *> fromChain;
35  std::vector<node *> toChain;
36  path *lastPath = 0;
37 
38  if (aMap->GetAbstractGraph(from->GetLabelL(kAbstractionLevel))->FindEdge(from->GetNum(), to->GetNum()))
39  return new path(from, new path(to));
40 
41  setupSearch(aMap, fromChain, from, toChain, to);
42 
43  if (fromChain.size() == 0)
44  return 0;
45 
46  do {
47  lastPath = buildNextAbstractPath(aMap, lastPath, fromChain, toChain, rp);
48  } while (lastPath==0 || lastPath->n->GetLabelL(kAbstractionLevel) > 0);
49 
50  return lastPath;
51 }
52 
54  std::vector<node *> &fromChain, node *from,
55  std::vector<node *> &toChain, node *to)
56 {
57  numLevels=0;
58 
59  nodesExpanded = 0;
60  nodesTouched = 0;
61 
62  if ((from == 0) || (to == 0) || (!aMap->Pathable(from, to)) || (from == to))
63  {
64  if (verbose)
65  {
66  if (!from)
67  printf("praStar2: from == 0\n");
68  if (!to)
69  printf("praStar2: to == 0\n");
70  if (from == to)
71  printf("praStar2: from == to\n");
72  if (from && to && (!aMap->Pathable(from, to)))
73  printf("praStar2: no path from %p to %p\n", (void*)from, (void*)to);
74  //cout << "praStar: no path from " << *from << " to " << *to << endl;
75  }
76  return;
77  }
78 
79  if (verbose)
80  printf("At nodes #%d and %d\n", from->GetNum(), to->GetNum());
81 
82  aMap->GetNumAbstractGraphs(from, to, fromChain, toChain);
83 
84  //Check for fixed plan level and dynamic plan level
85  selectTopAbstractionLevel(aMap, fromChain,toChain);
86 
87 }
88 
90  std::vector<node *> &fromChain,
91  std::vector<node *> & toChain)
92 {
93  if (fixedPlanLevel != -1)
94  {
95  if (verbose) std::cout<<"fixed set\n";
96  // We've manually chosen some top level to use
97  while (((int)fromChain.size() > 1) && ((int)toChain.size() > fixedPlanLevel + 1))
98  {
99  toChain.pop_back();
100  fromChain.pop_back();
101  }
102  }
103  else if (planFromMiddle)
104  {
105  if (verbose) std::cout<<"plan from middle\n";
106  // Dynamically find middle of hierarchy to start planning
107 
108  unsigned int previousSize = fromChain.size();
109  int minNode = (int)(2*sqrt(aMap->GetAbstractGraph(aMap->GetAbstractionLevel(fromChain[0]))->GetNumNodes()));
110 
111  while ((fromChain.size() > 2) &&
112  ((fromChain.size() > (previousSize)/2) ||
113  (aMap->GetAbstractGraph(fromChain.size())->GetNumNodes() < minNode)))
114  {
115  toChain.pop_back();
116  fromChain.pop_back();
117  }
118  }
119  topLevel = toChain.size() -1;
120 
121  if (verbose)
122  std::cout<<"Top praStar level: " << (toChain.size() -1) <<std::endl;
123 }
124 
125 
127  std::vector<node *> &fromChain,
128  std::vector<node *> &toChain,
130 {
131  numLevels++;
132  if (verbose)
133  std::cout<<"Now finding a path on level " <<(int)(toChain.size() -1) <<std::endl;
134 
135  node *to, *from, *hTarget = 0;
136  to = toChain.back();
137  from = fromChain.back();
138  toChain.pop_back();
139  fromChain.pop_back();
140 
141  if (skip==0 || skip<-1)
142  {
143 
144  //Go down one level each time - don't need to do anything else
145  }
146  else if (skip==-1)
147  {
148 
149  //Top level + bottom level only
150  while(toChain.size()>1)
151  {
152 
153  toChain.pop_back();
154  fromChain.pop_back();
155  }
156  }
157  else{
158  // Skip some levels
159  // If we get to the bottom early, we skip less than skip
160  int skipme = skip;
161  while(toChain.size()>1 && skipme > 0)
162  {
163 
164  toChain.pop_back();
165  fromChain.pop_back();
166  skipme--;
167  }
168  }
169 
170 
171  if (verbose)
172  printf("Expanded %d nodes before doing level %d\n", nodesExpanded, (int)from->GetLabelL(kAbstractionLevel));
173 
174  if (verbose)
175  printf("Building path from %d to %d (%ld/%ld)\n",
176  from->GetNum(), to->GetNum(), from->GetLabelL(kParent), to->GetLabelL(kParent));
177 
178  std::vector<node *> eligibleNodeParents;
179 
180  if (lastPath)
181  {
182  // cut path down to size of partial path limit
183  if (partialLimit > 0)
184  {
185  path *trav = lastPath;
186 
187  for (int x = 0; x < partialLimit; x++)
188  if (trav->next)
189  trav = trav->next;
190  // we don't need to reset the target if we have a complete path
191  // but we do if our complete path doesn't end in our target node
192  if ((trav->next != 0) || ((trav->next == 0) && ((int)trav->n->GetNum() != to->GetLabelL(kParent))))
193  {
194  to = trav->n;
195  if (trav->next)
196  hTarget = trav->next->n;
197  else
198  hTarget = to;
199  delete trav->next;
200  trav->next = 0;
201  if (verbose) printf("Setting target parent to %d\n", to->GetNum());
202  }
203  }
204 
205  Graph *g = aMap->GetAbstractGraph(lastPath->n->GetLabelL(kAbstractionLevel));
206 
207  // find eligible nodes for lower level expansions
208  for (path *trav = lastPath; trav; trav = trav->next)
209  {
210  if (expandSearchRadius)
211  {
212  edge_iterator ei = trav->n->getEdgeIter();
213  for (edge *e = trav->n->edgeIterNext(ei); e; e = trav->n->edgeIterNext(ei))
214  {
215  if (e->getFrom() == trav->n->GetNum())
216  eligibleNodeParents.push_back(g->GetNode(e->getTo()));
217  else
218  eligibleNodeParents.push_back(g->GetNode(e->getFrom()));
219  }
220  }
221  eligibleNodeParents.push_back(trav->n);
222  }
223  }
224 
225  cAStar.setCorridor(&eligibleNodeParents);
226  delete lastPath;
227  path *result;
228 
229  if (hTarget != 0)
230  {
232  result = cAStar.getBestPath(aMap, fromChain[0], toChain[0], from, to, rp);
233  else
234  result = cAStar.getBestPath(aMap, from, to, hTarget, rp);
235  }
236  else {
237  result = cAStar.GetPath(aMap, from, to, rp);
238  }
241  return result;
242 }
243 
244 path *praStar2::trimPath(path *lastPath, node *origDest)
245 {
246  if (partialLimit != -1)
247  {
248  int parent = -1;
249  path *change = 0, *last = 0;
250  for (path *trav = lastPath; trav; trav = trav->next)
251  {
252  if (trav->n == origDest)
253  return lastPath;
254  if (trav->n->GetLabelL(kParent) != parent)
255  {
256  parent = trav->n->GetLabelL(kParent);
257  change = last;
258  }
259  last = trav;
260  }
261  if (change)
262  {
263  delete change->next;
264  change->next = 0;
265  }
266  }
267  return lastPath;
268 }
verbose
static const int verbose
Definition: PRAStar2.cpp:16
GraphAbstraction
A generic class for basic operations on Graph abstractions.
Definition: GraphAbstraction.h:63
GraphAbstractionConstants
Definition: GraphAbstraction.h:22
praStar2::numLevels
int numLevels
Definition: PRAStar2.h:90
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
SearchAlgorithm::GetNodesTouched
uint64_t GetNodesTouched()
Definition: SearchAlgorithm.h:32
GraphAbstraction::GetAbstractGraph
Graph * GetAbstractGraph(int level)
return the abstract Graph at the given level
Definition: GraphAbstraction.h:74
praStar2::trimPath
path * trimPath(path *lastPath, node *origDest)
Definition: PRAStar2.cpp:244
praStar2::setupSearch
void setupSearch(GraphAbstraction *aMap, std::vector< node * > &fromChain, node *from, std::vector< node * > &toChain, node *to)
Definition: PRAStar2.cpp:53
praStar2::fixedPlanLevel
int fixedPlanLevel
Definition: PRAStar2.h:87
path::n
node * n
Definition: Path.h:22
edge_iterator
std::vector< edge * >::const_iterator edge_iterator
Definition: Graph.h:30
FPUtil.h
SearchAlgorithm::GetNodesExpanded
uint64_t GetNodesExpanded()
Definition: SearchAlgorithm.h:31
SearchAlgorithm::nodesTouched
uint32_t nodesTouched
Definition: SearchAlgorithm.h:37
praStar2::cAStar
corridorAStar cAStar
Definition: PRAStar2.h:83
Graph
A generic Graph class.
Definition: Graph.h:66
Graph::GetNode
node * GetNode(unsigned long num)
Definition: Graph.cpp:152
GraphAbstraction::GetAbstractionLevel
long GetAbstractionLevel(node *which)
Definition: GraphAbstraction.h:92
praStar2::buildNextAbstractPath
path * buildNextAbstractPath(GraphAbstraction *, path *lastPath, std::vector< node * > &fromChain, std::vector< node * > &toChain, reservationProvider *)
Definition: PRAStar2.cpp:126
praStar2::praStar2
praStar2()
Definition: PRAStar2.cpp:18
PRAStar2.h
praStar2::planFromMiddle
bool planFromMiddle
Definition: PRAStar2.h:86
GraphAbstraction::Pathable
virtual bool Pathable(node *from, node *to)=0
is there a legal path between these 2 nodes?
Graph::getEdgeIter
edge_iterator getEdgeIter() const
Definition: Graph.cpp:315
praStar2::algName
char algName[30]
Definition: PRAStar2.h:84
SearchAlgorithm::nodesExpanded
uint32_t nodesExpanded
Definition: SearchAlgorithm.h:36
GraphAbstractionConstants::kAbstractionLevel
@ kAbstractionLevel
Definition: GraphAbstraction.h:25
praStar2::partialLimit
int partialLimit
Definition: PRAStar2.h:80
Graph::GetNumNodes
int GetNumNodes()
Definition: Graph.cpp:403
path
std::vector< xyLoc > path
Definition: Sample.cpp:43
GraphAbstraction::GetNumAbstractGraphs
void GetNumAbstractGraphs(node *from, node *to, std::vector< node * > &fromChain, std::vector< node * > &toChain)
given 2 nodes, find as much of their hierarchy that exists in the Graph
Definition: GraphAbstraction.cpp:39
corridorAStar::GetPath
path * GetPath(GraphAbstraction *aMap, node *from, node *to, reservationProvider *rp=0)
Definition: CorridorAStar.cpp:28
praStar2::expandSearchRadius
bool expandSearchRadius
Definition: PRAStar2.h:82
praStar2::topLevel
int topLevel
Definition: PRAStar2.h:89
node::GetNum
unsigned int GetNum() const
Definition: Graph.h:176
corridorAStar::getBestPath
path * getBestPath(GraphAbstraction *aMap, node *from, node *to, node *hGoal, reservationProvider *rp=0)
get the best path from FROM to TO.
Definition: CorridorAStar.cpp:33
reservationProvider
Definition: ReservationProvider.h:33
SearchAlgorithm
A generic algorithm which can be used for pathfinding.
Definition: SearchAlgorithm.h:25
corridorAStar::setCorridor
void setCorridor(const std::vector< node * > *)
Definition: CorridorAStar.cpp:23
GraphAbstractionConstants::kParent
@ kParent
Definition: GraphAbstraction.h:27
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
praStar2::selectTopAbstractionLevel
void selectTopAbstractionLevel(GraphAbstraction *aMap, std::vector< node * > &fromChain, std::vector< node * > &toChain)
Definition: PRAStar2.cpp:89
praStar2::skip
int skip
Definition: PRAStar2.h:88
praStar2::GetPath
virtual path * GetPath(GraphAbstraction *aMap, node *from, node *to, reservationProvider *rp=0)
Definition: PRAStar2.cpp:32
praStar2::enhancedAbstractPathing
bool enhancedAbstractPathing
Definition: PRAStar2.h:81
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