HOG2
AStar3.cpp
Go to the documentation of this file.
1 /*
2  * $Id: aStar3.cpp
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 9/29/04.
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 "FPUtil.h"
13 #include "AStar3.h"
14 #include "Heap.h"
15 #include <string.h>
16 
17 using namespace GraphAbstractionConstants;
18 static const int verbose = 0;
19 
20 // The constructor
21 aStarOld::aStarOld(double _weight, bool _doPathDraw)
23 {
24  wh = _weight;
25  doPathDraw = _doPathDraw;
26  // Generate algorithm's name
27  if (fequal(wh,1.0))
28  strcpy(aStarName,"aStarOld");
29  else
30  sprintf(aStarName,"aStarOld(%1.1f)",wh);
31 }
32 
33 
34 // The same A*, but counts the number of states expanded
36 {
37  // Reset the number of states expanded
38  nodesExpanded = 0;
39  nodesTouched = 0;
40 
41  if ((from == 0) || (to == 0) || (!aMap->Pathable(from, to)) || (from == to))
42  return 0;
43  map = aMap;
45  Heap *openList = new Heap(30);
46  std::vector<node *> closedList;
47  node *n;
48 
49  // label start node cost 0
50  n = from;
51  n->SetLabelF(kTemporaryLabel, wh*map->h(n, to));
52  n->markEdge(0);
53 
54  while (1)
55  {
56  nodesExpanded++;
57  edge_iterator ei;
58 
59  // move current node onto closed list
60  // mark node with its location in the closed list
61  closedList.push_back(n);
62  n->key = closedList.size()-1;
63 
64  if (verbose)
65  printf("Working on %d with cost %1.2f\n", n->GetNum(), n->GetLabelF(kTemporaryLabel));
66 
67  ei = n->getEdgeIter();
68 
69  // iterate over all the children
70  for (edge *e = n->edgeIterNext(ei); e; e = n->edgeIterNext(ei))
71  {
72  nodesTouched++;
73  unsigned int which;
74  if ((which = e->getFrom()) == n->GetNum()) which = e->getTo();
75 
76  node *nextChild = g->GetNode(which);
77 
78  // if it's on the open list, we can still update the weight
79  if (openList->IsIn(nextChild))
80  {
81  //nodesExpanded++;
82  relaxEdge(openList, g, e, n->GetNum(), which, to);
83  }
84  else if (rp && (from->GetLabelL(kAbstractionLevel)==0) && (nextChild != to) &&
85  rp->nodeOccupied(nextChild))
86  {
87  //printf("Can't path to %d, %d\n", (unsigned int)nextChild->GetLabelL(kFirstData), (unsigned int)nextChild->GetLabelL(kFirstData+1));
88  closedList.push_back(nextChild);
89  nextChild->key = closedList.size()-1;
90  // ignore this tile if occupied.
91  }
92  // if it's not on the open list, then add it to the open list
93  else if ((nextChild->key >= closedList.size()) ||
94  (closedList[nextChild->key] != nextChild))
95  {
96  nextChild->SetLabelF(kTemporaryLabel, MAXINT);
97  nextChild->SetKeyLabel(kTemporaryLabel);
98  nextChild->markEdge(0);
99  openList->Add(nextChild);
100  if (verbose)
101  printf("Adding neighbor/child %d\n", which);
102  //nodesExpanded++;
103  relaxEdge(openList, g, e, n->GetNum(), which, to);
104  }
105  }
106 
107  // get the next (the best) node off the open list
108  n = (node*)openList->Remove();
109 
110  // this means we have expanded all reachable nodes and there is no path
111  if (n == 0) { delete openList; return 0; }
112  if (verbose) printf("Expanding %d\n", n->GetNum());
113  if (n == to) break; // we found the goal
114  }
115  delete openList;
116  return extractBestPath(g, n->GetNum());
117 }
118 
119 // this is the standard definition of relaxation as in Introduction to Algorithms (cormen, leiserson and rivest)
120 void aStarOld::relaxEdge(Heap *nodeHeap, Graph *g, edge *e, int source, int nextNode, node *d)
121 {
122  double weight;
123  node *from = g->GetNode(source);
124  node *to = g->GetNode(nextNode);
125  weight = from->GetLabelF(kTemporaryLabel)-wh*map->h(from, d)+wh*map->h(to, d)+e->GetWeight();
126  if (fless(weight, to->GetLabelF(kTemporaryLabel)))
127  {
128  if (verbose)
129  printf("Updating %d to %1.2f from %1.2f\n", nextNode, weight, to->GetLabelF(kTemporaryLabel));
130  to->SetLabelF(kTemporaryLabel, weight);
131  nodeHeap->DecreaseKey(to);
132  // this is the edge used to get to this node in the min. path tree
133  to->markEdge(e);
134  }
135 }
136 
137 path *aStarOld::extractBestPath(Graph *g, unsigned int current)
138 {
139  path *p = 0;
140  edge *e;
141  // extract best path from Graph -- each node has a single parent in the Graph which is the marked edge
142  // for visuallization purposes, an edge can be marked meaning it will be drawn in white
143  while ((e = g->GetNode(current)->getMarkedEdge()))
144  {
145  if (verbose) printf("%d <- ", current);
146 
147  p = new path(g->GetNode(current), p);
148 
149  if (doPathDraw)
150  e->setMarked(true);
151 
152  if (e->getFrom() == current)
153  current = e->getTo();
154  else
155  current = e->getFrom();
156  }
157  p = new path(g->GetNode(current), p);
158  if (verbose) printf("%d\n", current);
159  return p;
160 }
GraphAbstraction
A generic class for basic operations on Graph abstractions.
Definition: GraphAbstraction.h:63
GraphAbstractionConstants
Definition: GraphAbstraction.h:22
aStarOld::extractBestPath
path * extractBestPath(Graph *g, unsigned int current)
Definition: AStar3.cpp:137
edge::GetWeight
double GetWeight()
Definition: Graph.h:140
node::getMarkedEdge
edge * getMarkedEdge()
Definition: Graph.h:228
node::SetLabelF
void SetLabelF(unsigned int index, double val) const
Definition: Graph.cpp:687
edge::getFrom
unsigned int getFrom() const
Definition: Graph.h:146
edge::getTo
unsigned int getTo() const
Definition: Graph.h:147
aStarOld::GetPath
path * GetPath(GraphAbstraction *aMap, node *from, node *to, reservationProvider *rp=0)
Definition: AStar3.cpp: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
Heap.h
aStarOld::map
GraphAbstraction * map
Definition: AStar3.h:37
d
mcData d[]
Definition: MotionCaptureMovement.cpp:21
edge::setMarked
void setMarked(bool marked)
Definition: Graph.h:149
aStarOld::wh
double wh
Definition: AStar3.h:38
edge_iterator
std::vector< edge * >::const_iterator edge_iterator
Definition: Graph.h:30
FPUtil.h
aStarOld::doPathDraw
bool doPathDraw
Definition: AStar3.h:40
SearchAlgorithm::nodesTouched
uint32_t nodesTouched
Definition: SearchAlgorithm.h:37
AStar3.h
Heap::DecreaseKey
void DecreaseKey(graph_object *val)
Indicate that the key for a particular object has decreased.
Definition: Heap.cpp:47
verbose
static const int verbose
Definition: AStar3.cpp:18
Graph
A generic Graph class.
Definition: Graph.h:66
aStarOld::relaxEdge
void relaxEdge(Heap *nodeHeap, Graph *g, edge *e, int source, int nextNode, node *to)
Definition: AStar3.cpp:120
Graph::GetNode
node * GetNode(unsigned long num)
Definition: Graph.cpp:152
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
node::SetKeyLabel
void SetKeyLabel(int which)
Definition: Graph.h:208
GraphAbstraction::Pathable
virtual bool Pathable(node *from, node *to)=0
is there a legal path between these 2 nodes?
fless
bool fless(double a, double b)
Definition: FPUtil.h:28
SearchAlgorithm::nodesExpanded
uint32_t nodesExpanded
Definition: SearchAlgorithm.h:36
GraphAbstractionConstants::kAbstractionLevel
@ kAbstractionLevel
Definition: GraphAbstraction.h:25
Heap::Remove
graph_object * Remove()
Remove the item with the lowest key from the Heap & re-heapify.
Definition: Heap.cpp:66
Heap::Add
void Add(graph_object *val)
Add object into Heap.
Definition: Heap.cpp:36
aStarOld::aStarName
char aStarName[128]
Definition: AStar3.h:39
aStarOld::aStarOld
aStarOld(double _w=1.0, bool _doPathDraw=true)
Definition: AStar3.cpp:21
path
std::vector< xyLoc > path
Definition: Sample.cpp:43
node::GetLabelF
double GetLabelF(unsigned int index) const
Definition: Graph.h:215
Heap
A simple & efficient Heap class which uses Graph objects.
Definition: Heap.h:27
node::GetNum
unsigned int GetNum() const
Definition: Graph.h:176
MAXINT
#define MAXINT
Definition: Graph.h:24
GraphAbstractionConstants::kTemporaryLabel
@ kTemporaryLabel
Definition: GraphAbstraction.h:29
reservationProvider
Definition: ReservationProvider.h:33
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
reservationProvider::nodeOccupied
virtual bool nodeOccupied(node *)=0
fequal
bool fequal(double a, double b, double tolerance=TOLERANCE)
Definition: FPUtil.h:32
node::edgeIterNext
edge * edgeIterNext(edge_iterator &) const
Definition: Graph.cpp:754
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
Heap::IsIn
bool IsIn(graph_object *val)
Returns true if the object is in the Heap.
Definition: Heap.cpp:55
edge
Edge class for connections between node in a Graph.
Definition: Graph.h:129