HOG2
GraphAbstraction.cpp
Go to the documentation of this file.
1 /*
2  * $Id: GraphAbstraction.cpp
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 1/11/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 
13 #include "GraphAbstraction.h"
14 #include <math.h>
15 #include <cassert>
16 
17 using namespace GraphAbstractionConstants;
18 using namespace std;
19 
20 enum {
21  kQuiet = 0x00,
22  kBuildGraph = 0x01,
23  kRepairGraph = 0x02,
25 };
26 
27 const static int verbose = kQuiet;//kRepairGraph;
28 
30 {
31 
32  while (abstractions.size() > 0)
33  {
34  delete abstractions.back();
35  abstractions.pop_back();
36  }
37 }
38 
40  std::vector<node *> &fromChain,
41  std::vector<node *> &toChain)
42 {
43  // while (from->GetLabelL(kParent) != to->GetLabelL(kParent))
44  while (!abstractions[from->GetLabelL(kAbstractionLevel)]->
45  FindEdge(from->GetNum(), to->GetNum()) &&
46  //(from->GetLabelL(kParent) != to->GetLabelL(kParent))
47  (from != to))
48  {
49  fromChain.push_back(from);
50  toChain.push_back(to);
51 
52  from = abstractions[from->GetLabelL(kAbstractionLevel)+1]->
53  GetNode(from->GetLabelL(kParent));
54 
55  to = abstractions[to->GetLabelL(kAbstractionLevel)+1]->
56  GetNode(to->GetLabelL(kParent));
57 
58  if (verbose&kBuildGraph)
59  printf("GetNumAbstractGraphs: Moving to nodes #%d and %d\n",
60  from->GetNum(), to->GetNum());
61  }
62  fromChain.push_back(from);
63  toChain.push_back(to);
64 }
65 
66 // get nth-level parent of which node
68 {
69  while ((which != NULL) && (which->GetLabelL(kAbstractionLevel) < n))
70  {
71  int nextLevel = which->GetLabelL(kAbstractionLevel)+1;
72  Graph *g = abstractions[nextLevel];
73  which = g->GetNode(which->GetLabelL(kParent));
74  }
75  return which;
76 }
77 
78 bool GraphAbstraction::IsParentOf(node *parent, node *child)
79 {
80  if (GetAbstractionLevel(child) > GetAbstractionLevel(parent))
81  return false;
82  while (GetAbstractionLevel(child) < GetAbstractionLevel(parent))
83  {
84  child = GetParent(child);
85  }
86  return (parent == child);
87 }
88 
90 {
91  for (unsigned int x = 0; x < abstractions.size(); x++)
92  {
93  Graph *g = abstractions[x];
94  edge_iterator ei = g->getEdgeIter();
95  for (edge *e = g->edgeIterNext(ei); e; e = g->edgeIterNext(ei))
96  {
97  e->setMarked(false);
98  }
99  }
100 }
101 
103 {
104  if ((p == 0) || (p->next == 0) || (p->n == 0) || (p->next->n == 0))
105  return 0.0;
106  return h(p->n, p->next->n)+distance(p->next);
107 }
108 
109 void GraphAbstraction::MeasureAbstractionValues(int level, double &n, double &n_dev, double &c, double &c_dev)
110 {
111  assert((level > 0) && (level < (int)abstractions.size()));
112  Graph *g = abstractions[level];
113 
114  std::vector<int> ns;
115  std::vector<int> cs;
116  n = 0; c = 0;
117  node_iterator ni = g->getNodeIter();
118  for (node *nd = g->nodeIterNext(ni); nd; nd = g->nodeIterNext(ni))
119  {
120  ns.push_back(nd->GetLabelL(kNumAbstractedNodes));
121  n += ns.back();
122  cs.push_back(ComputeWidth(nd));
123  c += cs.back();
124  //printf("node %d: #%d width:%d\n", nd->GetNum(), ns.back(), cs.back());
125  }
126  n/= ns.size();
127  c/= cs.size();
128  n_dev = 0;
129  c_dev = 0;
130  for (unsigned int x = 0; x < ns.size(); x++)
131  {
132  n_dev += (ns[x]-n)*(ns[x]-n);
133  c_dev += (cs[x]-c)*(cs[x]-c);
134  }
135  n_dev /= ns.size();
136  c_dev /= cs.size();
137  n_dev = sqrtf(n_dev);
138  c_dev = sqrtf(c_dev);
139 }
140 
142 {
143 // printf("New WIDTH (%d)\n", n->GetNum());
144  int width = 0;
145  for (int child = 0; child < n->GetLabelL(kNumAbstractedNodes); child++)
146  {
147  width = std::max(width, WidthBFS(GetNthChild(n, child), n));
148  }
149  return width;
150 }
151 
153 {
154  std::vector<int> depth;
155  std::vector<node *> q;
156  Graph *g = GetAbstractGraph(child);
157 
158  q.push_back(child);
159  child->key = 0;
160  depth.push_back(0);
161 
162  for (unsigned int x = 0; x < q.size(); x++)
163  {
164 // printf("Handling node: %d\n", q[x]->GetNum());
165  neighbor_iterator ni = q[x]->getNeighborIter();
166  for (int next = q[x]->nodeNeighborNext(ni); next != -1; next = q[x]->nodeNeighborNext(ni))
167  {
168  node *neighbor = g->GetNode(next);
169  if ((neighbor->key < q.size()) && (q[neighbor->key] == neighbor))
170  {
171 // printf(" neighbor %d in Q\n", neighbor->GetNum());
172  continue;
173  }
174  if (neighbor->GetLabelL(kParent) == (int)parent->GetNum())
175  {
176 // printf(" neighbor %d onto Q(%d) depth (%d)\n", neighbor->GetNum(), q.size(), depth[x]+1);
177  neighbor->key = q.size();
178  q.push_back(neighbor);
179  depth.push_back(depth[x]+1);
180  }
181  }
182  }
183  return depth.back();
184 }
185 
187 {
188  if ((level > (int)abstractions.size()) || (level <= 0))
189  return 0.0f;
190  Graph *g = abstractions[level];
191 
192  std::vector<double> widths;
193 
194  double sum = 0;
195  node_iterator ni = g->getNodeIter();
196  for (node *nd = g->nodeIterNext(ni); nd; nd = g->nodeIterNext(ni))
197  {
198  double val = MeasureExpectedNodeWidth(nd);
199  // ignore dead-end nodes
200  if (val != 0)
201  {
202  widths.push_back(val);
203  sum += val;
204  //printf("node %d: expected width:%f\n", nd->GetNum(), val);
205  }
206  }
207  if (widths.size() > 0)
208  return sum/widths.size();
209  return 0;
210 }
211 
213 {
214  // for each edge, the number of edges at that depth
215  std::vector<std::vector<int> > edgeInfo;
216  // the total number of edges for this child
217  std::vector<int> sums;
218  std::vector<double> value;
219 
220  edgeInfo.resize(n->GetLabelL(kNumAbstractedNodes));
221  value.resize(n->GetLabelL(kNumAbstractedNodes));
222 
223  double expectedWidth = 0;
224  int totalExternalEdges = 0;
225  for (int child = 0; child < n->GetLabelL(kNumAbstractedNodes); child++)
226  {
227  node *c = GetNthChild(n, child);
228  CountEdgesAtDistance(c, n, edgeInfo[child]);
229  sums.push_back(0);
230  for (unsigned int x = 0; x < edgeInfo[child].size(); x++)
231  {
232  sums.back() += edgeInfo[child][x];
233 // printf("Node %d child %d dist %d has %d edges\n",
234 // n->GetNum(), child, x, edgeInfo[child][x]);
235  }
236 // printf("%d total edges [%d]\n", sums[child], child);
237  }
238 
239  for (int child = 0; child < n->GetLabelL(kNumAbstractedNodes); child++)
240  {
241  double dist = 0;
242  // this node has at least one external edge
243  // and two external edges total
244  if ((edgeInfo[child][0] != 0) && sums[child] > 1)
245  {
246  totalExternalEdges += edgeInfo[child][0];
247  for (unsigned int x = 0; x < edgeInfo[child].size(); x++)
248  {
249  if (edgeInfo[child][x] > 0)
250  {
251  if (x == 0)
252  dist += (edgeInfo[child][x]-1.0)*(x+1);
253  else
254  dist += (edgeInfo[child][x])*(x+1);
255  }
256  }
257  dist /= (sums[child]-1);
258  }
259 // printf("Average width = %f\n", dist);
260  value[child] = dist;
261  }
262 
263  if (totalExternalEdges != 0)
264  {
265  for (int child = 0; child < n->GetLabelL(kNumAbstractedNodes); child++)
266  {
267  expectedWidth += (value[child]*edgeInfo[child][0])/(double)totalExternalEdges;
268  }
269  }
270 // printf("Expected width = %f\n", expectedWidth);
271  return expectedWidth;
272 }
273 
274 // get the number of edges that n has outside of p
276 {
277  int count = 0;
279  Graph *g = GetAbstractGraph(n);
280  for (int next = n->nodeNeighborNext(ni); next != -1; next = n->nodeNeighborNext(ni))
281  {
282  node *nb = g->GetNode(next);
283  if (GetParent(nb) != p)
284  count++;
285  }
286  return count;
287 }
288 
289 // count the number of external edges the child has from the parent at
290 // each distance
291 int GraphAbstraction::CountEdgesAtDistance(node *child, node *parent, std::vector<int> &dists)
292 {
293  dists.resize(0);
294 
295  std::vector<unsigned int> depth;
296  std::vector<node *> q;
297  Graph *g = GetAbstractGraph(child);
298 
299  q.push_back(child);
300  child->key = 0;
301  depth.push_back(0);
302 
303  for (unsigned int x = 0; x < q.size(); x++)
304  {
305  // printf("Handling node: %d\n", q[x]->GetNum());
306  neighbor_iterator ni = q[x]->getNeighborIter();
307  if (depth[x]+1 > dists.size())
308  dists.resize(depth[x]+1);
309  dists[depth[x]] += GetNumExternalEdges(q[x], parent);
310 
311  for (int next = q[x]->nodeNeighborNext(ni); next != -1; next = q[x]->nodeNeighborNext(ni))
312  {
313  node *neighbor = g->GetNode(next);
314  if ((neighbor->key < q.size()) && (q[neighbor->key] == neighbor))
315  {
316  // printf(" neighbor %d in Q\n", neighbor->GetNum());
317  continue;
318  }
319  if (neighbor->GetLabelL(kParent) == (int)parent->GetNum())
320  {
321  // printf(" neighbor %d onto Q(%d) depth (%d)\n", neighbor->GetNum(), q.size(), depth[x]+1);
322  neighbor->key = q.size();
323  q.push_back(neighbor);
324  depth.push_back(depth[x]+1);
325  }
326  }
327  }
328  return depth.back();
329 }
330 
332 {
333  while (GetAbstractionLevel(n) != 0)
334  n = GetNthChild(n, random()%GetNumChildren(n));
335  return n;
336 }
verbose
const static int verbose
Definition: GraphAbstraction.cpp:27
GraphAbstractionConstants
Definition: GraphAbstraction.h:22
kMiscMessages
@ kMiscMessages
Definition: GraphAbstraction.cpp:24
graphMove
Definition: GraphEnvironment.h:34
GraphAbstraction::distance
double distance(path *p)
length in distance of a path
Definition: GraphAbstraction.cpp:102
GraphAbstraction::~GraphAbstraction
virtual ~GraphAbstraction()
Definition: GraphAbstraction.cpp:29
neighbor_iterator
unsigned int neighbor_iterator
Definition: Graph.h:34
graph_object::key
unsigned int key
Definition: Graph.h:54
Graph::nodeIterNext
node * nodeIterNext(node_iterator &) const
Definition: Graph.cpp:303
path::n
node * n
Definition: Path.h:22
edge_iterator
std::vector< edge * >::const_iterator edge_iterator
Definition: Graph.h:30
width
int width
Definition: SFML_HOG.cpp:54
GraphAbstraction::ClearMarkedNodes
void ClearMarkedNodes()
rebuild hierarchy from original domain *‍/
Definition: GraphAbstraction.cpp:89
Graph
A generic Graph class.
Definition: Graph.h:66
Graph::GetNode
node * GetNode(unsigned long num)
Definition: Graph.cpp:152
Graph::edgeIterNext
edge * edgeIterNext(edge_iterator &) const
Definition: Graph.cpp:320
GraphAbstraction::CountEdgesAtDistance
int CountEdgesAtDistance(node *child, node *parent, std::vector< int > &dists)
Definition: GraphAbstraction.cpp:291
node_iterator
std::vector< node * >::const_iterator node_iterator
Definition: Graph.h:33
GraphAbstractionConstants::kNumAbstractedNodes
@ kNumAbstractedNodes
Definition: GraphAbstraction.h:26
Graph::getEdgeIter
edge_iterator getEdgeIter() const
Definition: Graph.cpp:315
GraphAbstraction::WidthBFS
int WidthBFS(node *child, node *parent)
Definition: GraphAbstraction.cpp:152
GraphAbstractionConstants::kAbstractionLevel
@ kAbstractionLevel
Definition: GraphAbstraction.h:25
GraphAbstraction::GetRandomGroundNodeFromNode
node * GetRandomGroundNodeFromNode(node *n)
Definition: GraphAbstraction.cpp:331
max
#define max(a, b)
Definition: MinimalSectorAbstraction.cpp:40
Graph::getNodeIter
node_iterator getNodeIter() const
Definition: Graph.cpp:298
node::nodeNeighborNext
int nodeNeighborNext(neighbor_iterator &) const
Definition: Graph.cpp:807
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
GraphAbstraction::ComputeWidth
int ComputeWidth(node *n)
Definition: GraphAbstraction.cpp:141
std
Definition: CanonicalGraphEnvironment.h:26
GraphAbstraction::MeasureExpectedNodeWidth
double MeasureExpectedNodeWidth(node *n)
Definition: GraphAbstraction.cpp:212
node::GetNum
unsigned int GetNum() const
Definition: Graph.h:176
GraphAbstraction::IsParentOf
bool IsParentOf(node *parent, node *child)
return true if the first node is a parent of or is equal two the second node
Definition: GraphAbstraction.cpp:78
GraphAbstraction::MeasureAverageNodeWidth
double MeasureAverageNodeWidth(int level)
Definition: GraphAbstraction.cpp:186
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::getNeighborIter
neighbor_iterator getNeighborIter() const
Definition: Graph.cpp:802
kBuildGraph
@ kBuildGraph
Definition: GraphAbstraction.cpp:22
kQuiet
@ kQuiet
Definition: GraphAbstraction.cpp:21
kRepairGraph
@ kRepairGraph
Definition: GraphAbstraction.cpp:23
GraphAbstraction::GetNthParent
node * GetNthParent(node *which, int n)
return nth level parent of which or null if it doesn't exist
Definition: GraphAbstraction.cpp:67
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
GraphAbstraction.h
GraphAbstraction::GetNumExternalEdges
int GetNumExternalEdges(node *n, node *p)
Definition: GraphAbstraction.cpp:275
GraphAbstraction::MeasureAbstractionValues
void MeasureAbstractionValues(int level, double &n, double &n_dev, double &c, double &c_dev)
Definition: GraphAbstraction.cpp:109
edge
Edge class for connections between node in a Graph.
Definition: Graph.h:129