PGROUTING  3.2
pgr_astar.hpp
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 
3 File: pgr_astar.hpp
4 
5 Copyright (c) 2015 Vicky Vergara
8 
9 ------
10 
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20 
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 
25  ********************************************************************PGR-GNU*/
26 
27 #ifndef INCLUDE_ASTAR_PGR_ASTAR_HPP_
28 #define INCLUDE_ASTAR_PGR_ASTAR_HPP_
29 #pragma once
30 
31 #include <boost/config.hpp>
32 #include <boost/graph/graph_traits.hpp>
33 #include <boost/graph/adjacency_list.hpp>
34 #include <boost/graph/astar_search.hpp>
35 
36 #include <cmath>
37 
38 
39 #include <deque>
40 #include <limits>
41 #include <algorithm>
42 #include <vector>
43 #include <set>
44 #include <map>
45 
49 
50 namespace pgrouting {
51 namespace algorithms {
52 
53 template < class G >
54 class Pgr_astar {
55  public:
56  typedef typename G::V V;
57  typedef typename G::B_G B_G;
58 
59 
60  void clear() {
61  predecessors.clear();
62  distances.clear();
63  }
64 
66 
67  Path astar(
70  G &graph,
71  int64_t start_vertex,
72  int64_t end_vertex,
73  int heuristic,
74  double factor,
75  double epsilon,
76  bool only_cost) {
77  clear();
78 
79  predecessors.resize(graph.num_vertices());
80  distances.resize(graph.num_vertices());
81 
82  if (!graph.has_vertex(start_vertex)
83  || !graph.has_vertex(end_vertex)) {
84  return Path(start_vertex, end_vertex);
85  }
86 
87  auto v_source(graph.get_V(start_vertex));
88  auto v_target(graph.get_V(end_vertex));
89 
90  // perform the algorithm
91  astar_1_to_1(graph, v_source, v_target, heuristic, factor, epsilon);
92 
93  auto solution = Path(graph, Path(graph,
94  v_source, v_target,
96  false), only_cost);
97 
98  return solution;
99  }
100 
102  std::deque<Path> astar(
103  G &graph,
104  int64_t start_vertex,
105  std::vector<int64_t> end_vertex,
106  int heuristic,
107  double factor,
108  double epsilon,
109  bool only_cost) {
110  clear();
111 
112  predecessors.resize(graph.num_vertices());
113  distances.resize(graph.num_vertices());
114 
115  if (!graph.has_vertex(start_vertex)) return std::deque<Path>();
116  auto v_source(graph.get_V(start_vertex));
117 
118  std::vector<V> v_targets;
119  for (const auto &vertex : end_vertex) {
120  if (graph.has_vertex(vertex)) {
121  v_targets.push_back(graph.get_V(vertex));
122  }
123  }
124 
125  astar_1_to_many(graph,
126  v_source,
127  v_targets,
128  heuristic,
129  factor,
130  epsilon);
131 
132  auto paths = get_paths(graph, v_source, v_targets, only_cost);
133 
134  std::stable_sort(paths.begin(), paths.end(),
135  [](const Path &e1, const Path &e2)->bool {
136  return e1.end_id() < e2.end_id();
137  });
138 
139  return paths;
140  }
141 
142  // preparation for many to many
143  std::deque<Path> astar(
144  G &graph,
145  std::vector<int64_t> start_vertex,
146  std::vector<int64_t> end_vertex,
147  int heuristic,
148  double factor,
149  double epsilon,
150  bool only_cost) {
151  std::deque<Path> paths;
152  for (const auto &start : start_vertex) {
153  auto r_paths = astar(graph, start, end_vertex,
154  heuristic, factor, epsilon, only_cost);
155  paths.insert(paths.begin(), r_paths.begin(), r_paths.end());
156  }
157 
158  std::sort(paths.begin(), paths.end(),
159  [](const Path &e1, const Path &e2)->bool {
160  return e1.end_id() < e2.end_id();
161  });
162  std::stable_sort(paths.begin(), paths.end(),
163  [](const Path &e1, const Path &e2)->bool {
164  return e1.start_id() < e2.start_id();
165  });
166  return paths;
167  }
168 
169  // preparation for parallel arrays
170  std::deque<Path> astar(
171  G &graph,
172  const std::vector<pgr_combination_t> &combinations,
173  int heuristic,
174  double factor,
175  double epsilon,
176  bool only_cost) {
177  // a call to 1 to many is faster for each of the sources
178  std::deque<Path> paths;
179 
180  // group targets per distinct source
181  std::map< int64_t, std::vector<int64_t> > vertex_map;
182  for (const pgr_combination_t &comb : combinations) {
183  std::map< int64_t, std::vector<int64_t> >::iterator it = vertex_map.find(comb.source);
184  if (it != vertex_map.end()) {
185  it->second.push_back(comb.target);
186  } else {
187  std::vector<int64_t > targets{comb.target};
188  vertex_map[comb.source] = targets;
189  }
190  }
191 
192  for (const auto &start_ends : vertex_map) {
193  auto r_paths = astar(
194  graph,
195  start_ends.first, start_ends.second,
196  heuristic, factor, epsilon, only_cost);
197  paths.insert(paths.end(), r_paths.begin(), r_paths.end());
198  }
199 
200  return paths;
201  }
203 
204 
205 
206  private:
208 
209  struct found_goals{};
210  std::vector< V > predecessors;
211  std::vector< double > distances;
212  std::deque< V > nodesInDistance;
214 
215  // heuristic for one goal
216  class distance_heuristic : public boost::astar_heuristic< B_G, double > {
217  public:
218  distance_heuristic(B_G &g, V goal, int heuristic, double factor)
219  : m_g(g),
220  m_factor(factor),
221  m_heuristic(heuristic) {
222  m_goals.insert(goal);
223  }
225  B_G &g,
226  const std::vector< V > &goals,
227  int heuristic,
228  double factor)
229  : m_g(g),
230  m_goals(goals.begin(), goals.end()),
231  m_factor(factor),
232  m_heuristic(heuristic) {}
233 
234  double operator()(V u) {
235  if (m_heuristic == 0) return 0;
236  if (m_goals.empty()) return 0;
237  double best_h((std::numeric_limits<double>::max)());
238  for (auto goal : m_goals) {
239  double current((std::numeric_limits<double>::max)());
240  double dx = m_g[goal].x() - m_g[u].x();
241  double dy = m_g[goal].y() - m_g[u].y();
242  switch (m_heuristic) {
243  case 0:
244  current = 0;
245  break;
246  case 1:
247  current = std::fabs((std::max)(dx, dy)) * m_factor;
248  break;
249  case 2:
250  current = std::fabs((std::min)(dx, dy)) * m_factor;
251  break;
252  case 3:
253  current = (dx * dx + dy * dy) * m_factor * m_factor;
254  break;
255  case 4:
256  current = std::sqrt(dx * dx + dy * dy) * m_factor;
257  break;
258  case 5:
259  current = (std::fabs(dx) + std::fabs(dy)) * m_factor;
260  break;
261  default:
262  current = 0;
263  }
264  if (current < best_h) {
265  best_h = current;
266  }
267  }
268  {
269  auto s_it = m_goals.find(u);
270  if (!(s_it == m_goals.end())) {
271  // found one more goal
272  m_goals.erase(s_it);
273  }
274  }
275  return best_h;
276  }
277 
278  private:
280  std::set< V > m_goals;
281  double m_factor;
283  }; // class distance_heuristic
284 
285 
287  class astar_one_goal_visitor : public boost::default_astar_visitor {
288  public:
289  explicit astar_one_goal_visitor(V goal) : m_goal(goal) {}
290  template <class B_G>
291  void examine_vertex(V u, B_G &g) {
292  if (u == m_goal)
293  throw found_goals();
294  // using g, otherwise is throws a warning
295  num_edges(g);
296  }
297  private:
299  }; // class astar_one_goal_visitor
300 
302  class astar_many_goals_visitor : public boost::default_astar_visitor {
303  public:
304  explicit astar_many_goals_visitor(const std::vector< V > &goals)
305  :m_goals(goals.begin(), goals.end()) {}
306  template <class B_G>
307  void examine_vertex(V u, B_G &g) {
308  auto s_it = m_goals.find(u);
309  if (s_it == m_goals.end()) return;
310  // found one more goal
311  m_goals.erase(s_it);
312  if (m_goals.size() == 0) throw found_goals();
313  num_edges(g);
314  }
315  private:
316  std::set< V > m_goals;
317  };
318 
319  /******************** IMPLEMENTTION ******************/
320 
321 
322 
325  G &graph,
326  V source,
327  V target,
328  int heuristic,
329  double factor,
330  double epsilon) {
331  bool found = false;
332  /* abort in case of an interruption occurs (e.g. the query is being cancelled) */
333  CHECK_FOR_INTERRUPTS();
334  try {
335  // Call A* named parameter interface
336  boost::astar_search(
337  graph.graph, source,
338  distance_heuristic(graph.graph, target,
339  heuristic, factor * epsilon),
340  boost::predecessor_map(&predecessors[0])
341  .weight_map(get(&pgrouting::Basic_edge::cost, graph.graph))
342  .distance_map(&distances[0])
343  .visitor(astar_one_goal_visitor(target)));
344  }
345  catch(found_goals &) {
346  found = true; // Target vertex found
347  }
348  return found;
349  }
350 
351 
354  G &graph,
355  V source,
356  const std::vector< V > &targets,
357  int heuristic,
358  double factor,
359  double epsilon) {
360  bool found = false;
361  /* abort in case of an interruption occurs (e.g. the query is being cancelled) */
362  CHECK_FOR_INTERRUPTS();
363  try {
364  boost::astar_search(
365  graph.graph, source,
367  graph.graph, targets,
368  heuristic, factor * epsilon),
369  boost::predecessor_map(&predecessors[0])
370  .weight_map(get(&pgrouting::Basic_edge::cost, graph.graph))
371  .distance_map(&distances[0])
372  .visitor(astar_many_goals_visitor(targets)));
373  }
374  catch(found_goals &) {
375  found = true; // Target vertex found
376  }
377  return found;
378  }
379 
380 
381  /*
382  * GET_PATHS
383  */
384 
385 
386  std::deque<Path> get_paths(
387  const G &graph,
388  V source,
389  const std::vector<V> &targets,
390  bool only_cost) const {
391  std::deque<Path> paths;
392  for (const auto &target : targets) {
393  auto p = Path(graph,
394  source, target,
396  false);
397  paths.push_back(Path(graph, p, only_cost));
398  }
399  return paths;
400  }
401 };
402 
403 
404 } // namespace algorithms
405 } // namespace pgrouting
406 
407 #endif // INCLUDE_ASTAR_PGR_ASTAR_HPP_
interruption.h
pgrouting::algorithms::Pgr_astar::distances
std::vector< double > distances
Definition: pgr_astar.hpp:211
Path
Definition: basePath_SSEC.hpp:47
pgr_base_graph.hpp
pgrouting::algorithms::Pgr_astar::distance_heuristic::distance_heuristic
distance_heuristic(B_G &g, const std::vector< V > &goals, int heuristic, double factor)
Definition: pgr_astar.hpp:224
pgrouting::algorithms::Pgr_astar::distance_heuristic::m_goals
std::set< V > m_goals
Definition: pgr_astar.hpp:280
pgrouting::algorithms::Pgr_astar::astar_many_goals_visitor::m_goals
std::set< V > m_goals
Definition: pgr_astar.hpp:316
pgrouting::algorithms::Pgr_astar::distance_heuristic::m_heuristic
int m_heuristic
Definition: pgr_astar.hpp:282
pgrouting::algorithms::Pgr_astar::clear
void clear()
Definition: pgr_astar.hpp:60
pgrouting::algorithms::Pgr_astar::B_G
G::B_G B_G
Definition: pgr_astar.hpp:57
pgrouting::algorithms::Pgr_astar::distance_heuristic::m_g
B_G & m_g
Definition: pgr_astar.hpp:279
pgrouting::algorithms::Pgr_astar::distance_heuristic
Definition: pgr_astar.hpp:216
pgrouting::algorithms::Pgr_astar::astar
std::deque< Path > astar(G &graph, std::vector< int64_t > start_vertex, std::vector< int64_t > end_vertex, int heuristic, double factor, double epsilon, bool only_cost)
Definition: pgr_astar.hpp:143
pgrouting::algorithms::Pgr_astar::astar_1_to_1
bool astar_1_to_1(G &graph, V source, V target, int heuristic, double factor, double epsilon)
Call to Astar 1 source to 1 target.
Definition: pgr_astar.hpp:324
pgrouting::algorithms::Pgr_astar::astar_many_goals_visitor::examine_vertex
void examine_vertex(V u, B_G &g)
Definition: pgr_astar.hpp:307
pgrouting::algorithms::Pgr_astar::astar_one_goal_visitor::astar_one_goal_visitor
astar_one_goal_visitor(V goal)
Definition: pgr_astar.hpp:289
pgr_combination_t
Definition: pgr_combination_t.h:43
pgrouting::algorithms::Pgr_astar::astar_1_to_many
bool astar_1_to_many(G &graph, V source, const std::vector< V > &targets, int heuristic, double factor, double epsilon)
Call to astar 1 source to many targets.
Definition: pgr_astar.hpp:353
pgrouting::algorithms::Pgr_astar::astar
std::deque< Path > astar(G &graph, const std::vector< pgr_combination_t > &combinations, int heuristic, double factor, double epsilon, bool only_cost)
Definition: pgr_astar.hpp:170
pgrouting::algorithms::Pgr_astar::distance_heuristic::distance_heuristic
distance_heuristic(B_G &g, V goal, int heuristic, double factor)
Definition: pgr_astar.hpp:218
pgrouting::algorithms::Pgr_astar::predecessors
std::vector< V > predecessors
Definition: pgr_astar.hpp:210
pgrouting::algorithms::Pgr_astar::astar_one_goal_visitor
visitor that terminates when we find the goal
Definition: pgr_astar.hpp:287
pgrouting::algorithms::Pgr_astar
Definition: pgr_astar.hpp:54
pgrouting::algorithms::Pgr_astar::astar_many_goals_visitor
class for stopping when all targets are found
Definition: pgr_astar.hpp:302
pgrouting::Basic_edge::cost
double cost
Definition: basic_edge.h:44
pgrouting::algorithms::Pgr_astar::astar_one_goal_visitor::m_goal
V m_goal
Definition: pgr_astar.hpp:298
pgrouting::algorithms::Pgr_astar::astar_one_goal_visitor::examine_vertex
void examine_vertex(V u, B_G &g)
Definition: pgr_astar.hpp:291
pgrouting::algorithms::Pgr_astar::distance_heuristic::operator()
double operator()(V u)
Definition: pgr_astar.hpp:234
pgrouting::alphashape::G
graph::Pgr_base_graph< BG, XY_vertex, Basic_edge > G
Definition: pgr_alphaShape.h:56
pgrouting::algorithms::Pgr_astar::found_goals
Definition: pgr_astar.hpp:209
pgrouting::algorithms::Pgr_astar::distance_heuristic::m_factor
double m_factor
Definition: pgr_astar.hpp:281
pgrouting::algorithms::Pgr_astar::get_paths
std::deque< Path > get_paths(const G &graph, V source, const std::vector< V > &targets, bool only_cost) const
Definition: pgr_astar.hpp:386
pgrouting::algorithms::Pgr_astar::astar
std::deque< Path > astar(G &graph, int64_t start_vertex, std::vector< int64_t > end_vertex, int heuristic, double factor, double epsilon, bool only_cost)
astar 1 to many
Definition: pgr_astar.hpp:102
pgrouting::alphashape::V
boost::graph_traits< BG >::vertex_descriptor V
Definition: pgr_alphaShape.h:58
pgrouting::algorithms::Pgr_astar::astar
Path astar(G &graph, int64_t start_vertex, int64_t end_vertex, int heuristic, double factor, double epsilon, bool only_cost)
one to one astar 1 to 1
Definition: pgr_astar.hpp:69
pgrouting::algorithms::Pgr_astar::astar_many_goals_visitor::astar_many_goals_visitor
astar_many_goals_visitor(const std::vector< V > &goals)
Definition: pgr_astar.hpp:304
pgrouting
Book keeping class for swapping orders between vehicles.
Definition: pgr_alphaShape.cpp:56
pgrouting::algorithms::Pgr_astar::V
G::V V
Definition: pgr_astar.hpp:56
pgrouting::algorithms::Pgr_astar::nodesInDistance
std::deque< V > nodesInDistance
Definition: pgr_astar.hpp:212
basePath_SSEC.hpp