LEMUR Packages: ompl_lemur or_lemur pr_bgl prpy_lemur
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Groups Pages
lazysp.h
Go to the documentation of this file.
1 
9 namespace pr_bgl
10 {
11 
40 template <class Graph,
41  class WMap, class WLazyMap, class IsEvaledMap,
42  class IncSP, class EvalStrategy, class LazySPVisitor>
43 bool lazysp(Graph & g,
44  typename boost::graph_traits<Graph>::vertex_descriptor v_start,
45  typename boost::graph_traits<Graph>::vertex_descriptor v_goal,
46  WMap wmap, WLazyMap wlazymap, IsEvaledMap isevaledmap,
47  std::vector<typename boost::graph_traits<Graph>::edge_descriptor> & path,
48  IncSP incsp, EvalStrategy evalstrategy, LazySPVisitor visitor)
49 {
50  typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
51  typedef typename boost::graph_traits<Graph>::edge_descriptor Edge;
52  typedef typename boost::property_traits<WLazyMap>::value_type weight_type;
53 
54  for (;;)
55  {
56  std::vector<Edge> incsp_path;
57 
58  visitor.search_begin();
59  weight_type pathlen = incsp.solve(g, v_start, v_goal, wlazymap, incsp_path);
60  visitor.search_end();
61 
62  if (pathlen == incsp.inf)
63  {
64  visitor.no_path();
65  return false;
66  }
67 
68  // compose vpath and eepath, determine if path already evaled
69  std::vector<Vertex> vpath;
70  std::vector< std::pair<Edge,bool> > eepath;
71  bool path_evaled = true;
72  vpath.push_back(source(incsp_path[0],g));
73  for (unsigned int ui=0; ui<incsp_path.size(); ui++)
74  {
75  Edge & e = incsp_path[ui];
76  vpath.push_back(target(e,g));
77  bool is_evaled = get(isevaledmap, e);
78  if (!is_evaled)
79  path_evaled = false;
80  eepath.push_back(std::make_pair(e, is_evaled));
81  }
82 
83  visitor.lazy_path(pathlen, vpath, eepath);
84 
85  if (path_evaled)
86  {
87  visitor.path_found();
88  for (unsigned int ui=0; ui<eepath.size(); ui++)
89  path.push_back(eepath[ui].first);
90  return true;
91  }
92 
93  // determine edges to evaluate
94  std::vector<Edge> to_evaluate;
95  visitor.selector_begin();
96  evalstrategy.get_to_evaluate(g, eepath, to_evaluate);
97  visitor.selector_end();
98  BOOST_ASSERT(to_evaluate.size());
99 
100  // perform the evaluations
101 
102  for (unsigned int ui=0; ui<to_evaluate.size(); ui++)
103  {
104  Edge & e = to_evaluate[ui];
105  //weight_type e_weight_old = get(wlazymap, e);
106 
107  visitor.eval_begin();
108  std::pair<weight_type, std::vector<Edge> > eval_result = get(wmap,e);
109  visitor.eval_end();
110 
111  visitor.edge_evaluate(e, eval_result.first);
112  put(wlazymap, e, eval_result.first);
113 
114  for (unsigned int ui2=0; ui2<eval_result.second.size(); ui2++)
115  {
116  incsp.update_notify(eval_result.second[ui2]);
117  }
118 
119  visitor.selector_notify_begin();
120  for (unsigned int ui2=0; ui2<eval_result.second.size(); ui2++)
121  evalstrategy.update_notify(eval_result.second[ui2], incsp.inf); // e_weight_old
122  visitor.selector_notify_end();
123  }
124 
125  }
126 }
127 
131 {
132 public:
133 
135 
136  template <class Vertex, class Edge>
137  inline void lazy_path(double length,
138  std::vector<Vertex> & vpath,
139  std::vector< std::pair<Edge,bool> > & eepath)
140  {
141  }
142 
143  inline void search_begin() {}
144  inline void search_end() {}
145 
146  inline void eval_begin() {}
147  inline void eval_end() {}
148 
149  inline void no_path() {}
150  inline void path_found() {}
151 
152  template <class Edge>
153  inline void edge_evaluate(Edge & e, double e_weight) {}
154 
155  inline void selector_begin() {}
156  inline void selector_end() {}
157 
158  inline void selector_notify_begin() {}
159  inline void selector_notify_end() {}
160 };
161 
162 
165 template <class A, class B>
167 {
168 public:
169  A visA;
170  B visB;
171  lazysp_visitor_pair(A visA, B visB): visA(visA), visB(visB) {}
172 
173  template <class Vertex, class Edge>
174  inline void lazy_path(double length,
175  std::vector<Vertex> & vpath,
176  std::vector< std::pair<Edge,bool> > & eepath)
177  {
178  visA.lazy_path(length, vpath, eepath);
179  visB.lazy_path(length, vpath, eepath);
180  }
181 
182  inline void search_begin()
183  {
184  visA.search_begin();
185  visB.search_begin();
186  }
187 
188  inline void search_end()
189  {
190  visA.search_end();
191  visB.search_end();
192  }
193 
194  inline void eval_begin()
195  {
196  visA.eval_begin();
197  visB.eval_begin();
198  }
199 
200  inline void eval_end()
201  {
202  visA.eval_end();
203  visB.eval_end();
204  }
205 
206  inline void no_path()
207  {
208  visA.no_path();
209  visB.no_path();
210  }
211 
212  inline void path_found()
213  {
214  visA.path_found();
215  visB.path_found();
216  }
217 
218  template <class Edge>
219  inline void edge_evaluate(Edge & e, double e_weight)
220  {
221  visA.edge_evaluate(e, e_weight);
222  visB.edge_evaluate(e, e_weight);
223  }
224 
225  inline void selector_begin()
226  {
227  visA.selector_begin();
228  visB.selector_begin();
229  }
230 
231  inline void selector_end()
232  {
233  visA.selector_end();
234  visB.selector_end();
235  }
236 
237  inline void selector_notify_begin()
238  {
239  visA.selector_notify_begin();
240  visB.selector_notify_begin();
241  }
242 
243  inline void selector_notify_end()
244  {
245  visA.selector_notify_end();
246  visB.selector_notify_end();
247  }
248 
249 };
250 
251 template <class A, class B>
253 make_lazysp_visitor_pair(A visA, B visB)
254 {
255  return lazysp_visitor_pair<A,B>(visA, visB);
256 }
257 
261 {
262 public:
263  template <class Graph>
264  void get_to_evaluate(
265  const Graph & g,
266  const std::vector< std::pair<typename boost::graph_traits<Graph>::edge_descriptor,bool> > & path,
267  std::vector<typename boost::graph_traits<Graph>::edge_descriptor> & to_evaluate)
268  {
269  unsigned int ui;
270  for (ui=0; ui<path.size(); ui++)
271  if (path[ui].second == false)
272  break;
273  if (ui<path.size())
274  to_evaluate.push_back(path[ui].first);
275  }
276  template <class Edge, class WeightType>
277  void update_notify(Edge e, WeightType e_weight_old) {}
278 };
279 
283 {
284 public:
285  template <class Graph>
286  void get_to_evaluate(
287  const Graph & g,
288  const std::vector< std::pair<typename boost::graph_traits<Graph>::edge_descriptor,bool> > & path,
289  std::vector<typename boost::graph_traits<Graph>::edge_descriptor> & to_evaluate)
290  {
291  int i;
292  for (i=path.size()-1; 0<=i; i--)
293  if (path[i].second == false)
294  break;
295  if (0<=i)
296  to_evaluate.push_back(path[i].first);
297  }
298  template <class Edge, class WeightType>
299  void update_notify(Edge e, WeightType e_weight_old) {}
300 };
301 
305 {
306 public:
309  bool do_fwd;
310  lazysp_selector_alt(): do_fwd(true) {}
311  template <class Graph>
312  void get_to_evaluate(
313  const Graph & g,
314  const std::vector< std::pair<typename boost::graph_traits<Graph>::edge_descriptor,bool> > & path,
315  std::vector<typename boost::graph_traits<Graph>::edge_descriptor> & to_evaluate)
316  {
317  if (do_fwd)
318  fwd.get_to_evaluate(g, path, to_evaluate);
319  else
320  rev.get_to_evaluate(g, path, to_evaluate);
321  do_fwd = !do_fwd;
322  }
323  template <class Edge, class WeightType>
324  void update_notify(Edge e, WeightType e_weight_old) {}
325 };
326 
330 {
331 public:
332  template <class Graph>
333  void get_to_evaluate(
334  const Graph & g,
335  const std::vector< std::pair<typename boost::graph_traits<Graph>::edge_descriptor,bool> > & path,
336  std::vector<typename boost::graph_traits<Graph>::edge_descriptor> & to_evaluate)
337  {
338  unsigned int ui, idx;
339  for (ui=0; ui<path.size(); ui++)
340  {
341  if (ui % 2 == 0)
342  idx = ui / 2;
343  else
344  idx = path.size() - (ui+1)/2;
345  if (path[idx].second == false)
346  break;
347  }
348  if (ui<path.size())
349  to_evaluate.push_back(path[idx].first);
350  }
351  template <class Edge, class WeightType>
352  void update_notify(Edge e, WeightType e_weight_old) {}
353 };
354 
358 {
359 public:
360  template <class Graph>
361  void get_to_evaluate(
362  const Graph & g,
363  const std::vector< std::pair<typename boost::graph_traits<Graph>::edge_descriptor,bool> > & path,
364  std::vector<typename boost::graph_traits<Graph>::edge_descriptor> & to_evaluate)
365  {
366  // dists = min(dist_backwards, dist_forwards)
367  // distance for now is just number of edges
368  // dist[e_evaled] = 0
369  int i;
370  std::vector<int> dists(path.size());
371  // forward
372  for (i=0; i<(int)path.size(); i++)
373  {
374  int fwd_dist;
375  if (path[i].second)
376  fwd_dist = 0;
377  else if (i==0)
378  fwd_dist = 1;
379  else
380  fwd_dist = dists[i-1] + 1;
381  dists[i] = fwd_dist;
382  }
383  // backwards
384  for (i=path.size()-1; i>=0; i--)
385  {
386  int rev_dist;
387  if (path[i].second)
388  rev_dist = 0;
389  else if (i==(int)path.size()-1)
390  rev_dist = 1;
391  else
392  rev_dist = dists[i+1] + 1;
393  if (rev_dist < dists[i])
394  dists[i] = rev_dist;
395  }
396  // choose max
397  int max = -1;
398  int max_i = 0;
399  for (i=0; i<(int)path.size(); i++)
400  {
401  if (max < dists[i])
402  {
403  max = dists[i];
404  max_i = i;
405  }
406  }
407  if (max < 0)
408  {
409  printf("error with max!\n");
410  abort();
411  }
412  to_evaluate.push_back(path[max_i].first);
413  }
414  template <class Edge, class WeightType>
415  void update_notify(Edge e, WeightType e_weight_old) {}
416 };
417 
421 {
422 public:
423  template <class Graph>
424  void get_to_evaluate(
425  const Graph & g,
426  const std::vector< std::pair<typename boost::graph_traits<Graph>::edge_descriptor,bool> > & path,
427  std::vector<typename boost::graph_traits<Graph>::edge_descriptor> & to_evaluate)
428  {
429  unsigned int ui;
430  for (ui=0; ui<path.size(); ui++)
431  if (path[ui].second == false)
432  break;
433  if (!(ui<path.size()))
434  return;
435  typename boost::graph_traits<Graph>::out_edge_iterator ei, ei_end;
436  for (boost::tie(ei,ei_end)=out_edges(source(path[ui].first,g),g); ei!=ei_end; ++ei)
437  to_evaluate.push_back(*ei);
438  }
439  template <class Edge, class WeightType>
440  void update_notify(Edge e, WeightType e_weight_old) {}
441 };
442 
443 } // namespace pr_bgl
Forward selector for pr_bgl::lazysp.
Definition: lazysp.h:260
Bisect selector for pr_bgl::lazysp.
Definition: lazysp.h:357
Reverse selector for pr_bgl::lazysp.
Definition: lazysp.h:282
FwdExpand selector for pr_bgl::lazysp.
Definition: lazysp.h:420
Even selector for pr_bgl::lazysp.
Definition: lazysp.h:329
Null visitor for pr_bgl::lazysp.
Definition: lazysp.h:130
Pair visitor for pr_bgl::lazysp.
Definition: lazysp.h:166
Alternate selector for pr_bgl::lazysp.
Definition: lazysp.h:304