HOG2
SpreadPRAStar.cpp
Go to the documentation of this file.
1 /*
2  * $Id: spreadPRAStar.cpp
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 6/27/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 "SpreadPRAStar.h"
13 #include "FPUtil.h"
14 
15 using namespace GraphAbstractionConstants;
16 static const int verbose = 0;
17 
19 {
20  setPartialPathLimit(-1);
21  lastPath = 0;
22  expandSearchRadius = true;
23 }
24 
26 {
27  std::vector<node *> fromChain;
28  std::vector<node *> toChain;
29  path *lastPth = 0;
30 
31  if (_aMap->GetAbstractGraph(from->GetLabelL(kAbstractionLevel))->FindEdge(from->GetNum(), to->GetNum()))
32  return new path(from, new path(to));
33 
34  setupSearch(_aMap, fromChain, from, toChain, to);
35  if (fromChain.size() == 0)
36  return 0;
37  do {
38  lastPth = buildNextAbstractPath(_aMap, lastPth, fromChain, toChain, _rp);
39  } while (lastPth && (lastPth->n->GetLabelL(kAbstractionLevel) > 0));
40  return lastPth;
41 }
42 
44 {
45  rp = _rp; start = s; end = e; aMap = _aMap;
46  startChain.resize(0);
47  endChain.resize(0);
48  setupSearch(aMap, startChain, start, endChain, end);
49  delete lastPath;
50  lastPath = 0;
51 }
52 
55 {
56  return -1;
57 }
58 
61 {
62  nodesExpanded = 0;
63  nodesTouched = 0;
64  if (startChain.size() == 0)
65  return 0;
66  lastPath = buildNextAbstractPath(aMap, lastPath, startChain, endChain, rp);
67  if (lastPath && (lastPath->n->GetLabelL(kAbstractionLevel) == 0))
68  {
69  path *p = lastPath;
70  lastPath = 0;
71  return p;
72  }
73  return 0;
74 }
75 
77  std::vector<node *> &fromChain, node *from,
78  std::vector<node *> &toChain, node *to)
79 {
80  nodesExpanded = 0;
81  nodesTouched = 0;
82 
83  if ((from == 0) || (to == 0) || (!_aMap->Pathable(from, to)) || (from == to))
84  {
85  if (verbose)
86  {
87  if (!from)
88  printf("spreadPRAStar: from == 0\n");
89  if (!to)
90  printf("spreadPRAStar: to == 0\n");
91  if (from == to)
92  printf("spreadPRAStar: from == to\n");
93  if (from && to && (!_aMap->Pathable(from, to)))
94  printf("spreadPRAStar: no path from %p to %p\n", (void*)from, (void*)to);
95  //cout << "praStar: no path from " << *from << " to " << *to << endl;
96  }
97  return;
98  }
99 
100  if (verbose)
101  printf("At nodes #%d and %d\n", from->GetNum(), to->GetNum());
102 // if (aMap->GetAbstractGraph(0)->FindEdge(from->GetNum(), to->GetNum()))
103 // { // we are 1 step away
104 // return new path(from, new path(to));
105 // }
106 
107  _aMap->GetNumAbstractGraphs(from, to, fromChain, toChain);
108  // assert(aMap->GetAbstractGraph(fromChain.back()->GetLabelL(kAbstractionLevel))->
109  // FindEdge(fromChain.back()->GetNum(), toChain.back()->GetNum()));
110 
111  unsigned int previousSize = fromChain.size();
112  int minNode = (int)(2*sqrt(_aMap->GetAbstractGraph(0)->GetNumNodes()));
113  while ((fromChain.size() > 2) && ((fromChain.size() > (previousSize)/2) ||
114  (_aMap->GetAbstractGraph(fromChain.size())->GetNumNodes() < minNode)))
115  {
116  toChain.pop_back();
117  fromChain.pop_back();
118  }
119 }
120 
122  std::vector<node *> &fromChain,
123  std::vector<node *> &toChain,
124  reservationProvider *_rp)
125 {
126  node *to, *from, *hTarget = 0;
127  to = toChain.back();
128  toChain.pop_back();
129  from = fromChain.back();
130  fromChain.pop_back();
131 
132  if (verbose)
133  printf("Expanded %d nodes before doing level %d\n", nodesExpanded, (int)from->GetLabelL(kAbstractionLevel));
134 
135  if (verbose)
136  printf("Building path from %d to %d (%ld/%ld)\n",
137  from->GetNum(), to->GetNum(), from->GetLabelL(kParent), to->GetLabelL(kParent));
138 
139  std::vector<node *> eligibleNodeParents;
140 
141  if (lastPth)
142  {
143  // cut path down to size of partial path limit
144  if (partialLimit > 0)
145  {
146  path *trav = lastPth;
147 
148  for (int x = 0; x < partialLimit; x++)
149  if (trav->next)
150  trav = trav->next;
151  // we don't need to reset the target if we have a complete path
152  // but we do if our complete path doesn't end in our target node
153  if ((trav->next != 0) || ((trav->next == 0) && ((long)trav->n->GetNum() != to->GetLabelL(kParent))))
154  {
155  to = trav->n;
156  if (trav->next)
157  hTarget = trav->next->n;
158  else
159  hTarget = to;
160  delete trav->next;
161  trav->next = 0;
162  }
163  }
164 
165  Graph *g = _aMap->GetAbstractGraph(lastPth->n->GetLabelL(kAbstractionLevel));
166  // find eligible nodes for lower level expansions
167  for (path *trav = lastPth; trav; trav = trav->next)
168  {
169  if (expandSearchRadius)
170  {
171  edge_iterator ei = trav->n->getEdgeIter();
172  for (edge *e = trav->n->edgeIterNext(ei); e; e = trav->n->edgeIterNext(ei)) {
173  if (e->getFrom() == trav->n->GetNum())
174  eligibleNodeParents.push_back(g->GetNode(e->getTo()));
175  else
176  eligibleNodeParents.push_back(g->GetNode(e->getFrom()));
177  }
178  }
179  eligibleNodeParents.push_back(trav->n);
180  }
181  }
182  cAStar.setCorridor(&eligibleNodeParents);
183  path *result;
184  if (hTarget != 0)
185  {
186  result = cAStar.getBestPath(_aMap, from, to, hTarget, _rp);
187  if (result == 0)
188  {
189  if (verbose) printf("NULL result from getBestPath in spreadPRAStar\n");
190  }
191  }
192  else {
193  result = cAStar.GetPath(_aMap, from, to, _rp);
194  if (result == 0)
195  {
196  if (verbose) printf("NULL result from GetPath in spreadPRAStar\n");
197  }
198  }
199  nodesExpanded += cAStar.GetNodesExpanded();
200  nodesTouched += cAStar.GetNodesTouched();
201  return result;
202 }
203 
204 path *spreadPRAStar::trimPath(path *lastPth, node *origDest)
205 {
206  if (partialLimit != -1)
207  {
208  int parent = -1;
209  path *change = 0, *last = 0;
210  for (path *trav = lastPth; trav; trav = trav->next)
211  {
212  if (trav->n == origDest)
213  return lastPth;
214  if (trav->n->GetLabelL(kParent) != parent)
215  {
216  parent = trav->n->GetLabelL(kParent);
217  change = last;
218  }
219  last = trav;
220  }
221  if (change)
222  {
223  delete change->next;
224  change->next = 0;
225  }
226  }
227  return lastPth;
228 }
GraphAbstraction
A generic class for basic operations on Graph abstractions.
Definition: GraphAbstraction.h:63
GraphAbstractionConstants
Definition: GraphAbstraction.h:22
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
GraphAbstraction::GetAbstractGraph
Graph * GetAbstractGraph(int level)
return the abstract Graph at the given level
Definition: GraphAbstraction.h:74
spreadPRAStar::getNumThinkSteps
int getNumThinkSteps()
how many times do we have to "think" to find the solution, return -1 if unknown
Definition: SpreadPRAStar.cpp:54
spreadPRAStar::trimPath
path * trimPath(path *lastPath, node *origDest)
Definition: SpreadPRAStar.cpp:204
path::n
node * n
Definition: Path.h:22
edge_iterator
std::vector< edge * >::const_iterator edge_iterator
Definition: Graph.h:30
FPUtil.h
Graph
A generic Graph class.
Definition: Graph.h:66
Graph::GetNode
node * GetNode(unsigned long num)
Definition: Graph.cpp:152
spreadPRAStar::buildNextAbstractPath
path * buildNextAbstractPath(GraphAbstraction *, path *lastPath, std::vector< node * > &fromChain, std::vector< node * > &toChain, reservationProvider *)
Definition: SpreadPRAStar.cpp:121
verbose
static const int verbose
Definition: SpreadPRAStar.cpp:16
spreadPRAStar::GetPath
virtual path * GetPath(GraphAbstraction *aMap, node *from, node *to, reservationProvider *rp=0)
Definition: SpreadPRAStar.cpp:25
spreadPRAStar::think
path * think()
do next processing for path, returns avaliability of path moves
Definition: SpreadPRAStar.cpp:60
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
spreadPRAStar::setTargets
void setTargets(GraphAbstraction *, node *, node *, reservationProvider *)
Definition: SpreadPRAStar.cpp:43
GraphAbstractionConstants::kAbstractionLevel
@ kAbstractionLevel
Definition: GraphAbstraction.h:25
Graph::GetNumNodes
int GetNumNodes()
Definition: Graph.cpp:403
path
std::vector< xyLoc > path
Definition: Sample.cpp:43
spreadPRAStar::setupSearch
void setupSearch(GraphAbstraction *aMap, std::vector< node * > &fromChain, node *from, std::vector< node * > &toChain, node *to)
Definition: SpreadPRAStar.cpp:76
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
node::GetNum
unsigned int GetNum() const
Definition: Graph.h:176
spreadPRAStar::spreadPRAStar
spreadPRAStar()
Definition: SpreadPRAStar.cpp:18
reservationProvider
Definition: ReservationProvider.h:33
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
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
SpreadPRAStar.h
edge
Edge class for connections between node in a Graph.
Definition: Graph.h:129