PGROUTING  3.2
pgr_bellman_ford.hpp
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 
3 Copyright (c) 2015 pgRouting developers
5 
6 Copyright (c) 2018 Sourabh Garg
7 Mail to: [email protected]
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_BELLMAN_FORD_PGR_BELLMAN_FORD_HPP_
28 #define INCLUDE_BELLMAN_FORD_PGR_BELLMAN_FORD_HPP_
29 #pragma once
30 
31 #include <boost/config.hpp>
32 #include <boost/graph/adjacency_list.hpp>
33 #include <boost/graph/bellman_ford_shortest_paths.hpp>
34 #include <deque>
35 #include <set>
36 #include <vector>
37 #include <algorithm>
38 #include <sstream>
39 #include <string>
40 #include <functional>
41 #include <limits>
42 #include <map>
47 
48 
49 
50 //******************************************
51 
52 template < class G >
54  public:
55  typedef typename G::V V;
56  typedef typename G::E E;
58 
60 
63  G &graph,
64  int64_t start_vertex,
65  int64_t end_vertex,
66  bool only_cost = false) {
67  clear();
68  log << std::string(__FUNCTION__) << "\n";
69 
70  // adjust predecessors and distances vectors
71  predecessors.resize(graph.num_vertices());
72  distances.resize(graph.num_vertices());
73 
74 
75  if (!graph.has_vertex(start_vertex)
76  || !graph.has_vertex(end_vertex)) {
77  return Path(start_vertex, end_vertex);
78  }
79 
80  // get the graphs source and target
81  auto v_source(graph.get_V(start_vertex));
82  auto v_target(graph.get_V(end_vertex));
83 
84  // perform the algorithm
85  bellman_ford_1_to_1(graph, v_source, v_target);
86 
87  // get the results
88  return Path(
89  graph,
90  v_source, v_target,
92  only_cost, true);
93  }
94 
95 
97  std::deque<Path> bellman_ford(
98  G &graph,
99  int64_t start_vertex,
100  const std::vector< int64_t > &end_vertex,
101  bool only_cost = false) {
102  // adjust predecessors and distances vectors
103  clear();
104  log << std::string(__FUNCTION__) << "\n";
105  predecessors.resize(graph.num_vertices());
106  distances.resize(graph.num_vertices());
107 
108  // get the graphs source and target
109  if (!graph.has_vertex(start_vertex))
110  return std::deque<Path>();
111  auto v_source(graph.get_V(start_vertex));
112 
113  std::set< V > s_v_targets;
114  for (const auto &vertex : end_vertex) {
115  if (graph.has_vertex(vertex)) {
116  s_v_targets.insert(graph.get_V(vertex));
117  }
118  }
119 
120  std::vector< V > v_targets(s_v_targets.begin(), s_v_targets.end());
121  // perform the algorithm
122  bellman_ford_1_to_many(graph, v_source);
123 
124  std::deque< Path > paths;
125  // get the results // route id are the targets
126  paths = get_paths(graph, v_source, v_targets, only_cost);
127 
128  std::stable_sort(paths.begin(), paths.end(),
129  [](const Path &e1, const Path &e2)->bool {
130  return e1.end_id() < e2.end_id();
131  });
132 
133  return paths;
134  }
135 
136  // BellmanFord many to 1
137  std::deque<Path> bellman_ford(
138  G &graph,
139  const std::vector < int64_t > &start_vertex,
140  int64_t end_vertex,
141  bool only_cost = false) {
142  std::deque<Path> paths;
143  log << std::string(__FUNCTION__) << "\n";
144  for (const auto &start : start_vertex) {
145  paths.push_back(
146  bellman_ford(graph, start, end_vertex, only_cost));
147  }
148 
149  std::stable_sort(paths.begin(), paths.end(),
150  [](const Path &e1, const Path &e2)->bool {
151  return e1.start_id() < e2.start_id();
152  });
153  return paths;
154  }
155 
156 
157  // BellmanFord many to many
158  std::deque<Path> bellman_ford(
159  G &graph,
160  const std::vector< int64_t > &start_vertex,
161  const std::vector< int64_t > &end_vertex,
162  bool only_cost = false) {
163  // a call to 1 to many is faster for each of the sources
164  std::deque<Path> paths;
165  log << std::string(__FUNCTION__) << "\n";
166 
167  for (const auto &start : start_vertex) {
168  auto r_paths = bellman_ford(graph, start, end_vertex, only_cost);
169  paths.insert(paths.begin(), r_paths.begin(), r_paths.end());
170  }
171 
172 
173  std::sort(paths.begin(), paths.end(),
174  [](const Path &e1, const Path &e2)->bool {
175  return e1.end_id() < e2.end_id();
176  });
177  std::stable_sort(paths.begin(), paths.end(),
178  [](const Path &e1, const Path &e2)->bool {
179  return e1.start_id() < e2.start_id();
180  });
181  return paths;
182  }
183 
184  // BellmanFord combinations
185  std::deque<Path> bellman_ford(
186  G &graph,
187  const std::vector<pgr_combination_t> &combinations,
188  bool only_cost = false) {
189  // a call to 1 to many is faster for each of the sources
190  std::deque<Path> paths;
191  log << std::string(__FUNCTION__) << "\n";
192 
193  // group targets per distinct source
194  std::map< int64_t, std::vector<int64_t> > vertex_map;
195  for (const pgr_combination_t &comb : combinations) {
196  std::map< int64_t, std::vector<int64_t> >::iterator it = vertex_map.find(comb.source);
197  if (it != vertex_map.end()) {
198  it->second.push_back(comb.target);
199  } else {
200  std::vector<int64_t > targets{comb.target};
201  vertex_map[comb.source] = targets;
202  }
203  }
204 
205  for (const auto &start_ends : vertex_map) {
206  std::deque<Path> result_paths = bellman_ford(
207  graph,
208  start_ends.first,
209  start_ends.second,
210  only_cost);
211  paths.insert(
212  paths.end(),
213  std::make_move_iterator(result_paths.begin()),
214  std::make_move_iterator(result_paths.end()));
215  }
216 
217  return paths;
218  }
219 
221 
222  private:
225  G &graph,
226  V source
227  ) {
228  log << std::string(__FUNCTION__) << "\n";
229  /* abort in case of an interruption occurs (e.g. the query is being cancelled) */
230  CHECK_FOR_INTERRUPTS();
231  try {
232  boost::bellman_ford_shortest_paths(
233  graph.graph,
234  static_cast<int>(graph.num_vertices()),
235  boost::predecessor_map(&predecessors[0])
236  .weight_map(get(&G::G_T_E::cost, graph.graph))
237  .distance_map(&distances[0])
238  .root_vertex(source));
239  } catch (boost::exception const& ex) {
240  (void)ex;
241  throw;
242  } catch (std::exception &e) {
243  (void)e;
244  throw;
245  } catch (...) {
246  throw;
247  }
248  return true;
249  }
252  G &graph,
253  V source) {
254  log << std::string(__FUNCTION__) << "\n";
255  /* abort in case of an interruption occurs (e.g. the query is being cancelled) */
256  CHECK_FOR_INTERRUPTS();
257  try {
258  boost::bellman_ford_shortest_paths(
259  graph.graph,
260  static_cast<int>(graph.num_vertices()),
261  boost::predecessor_map(&predecessors[0])
262  .weight_map(get(&G::G_T_E::cost, graph.graph))
263  .distance_map(&distances[0])
264  .root_vertex(source));
265  } catch (boost::exception const& ex) {
266  (void)ex;
267  throw;
268  } catch (std::exception &e) {
269  (void)e;
270  throw;
271  } catch (...) {
272  throw;
273  }
274  return true;
275  }
276 
277 
278  // To Empty predecessors and distances vector for each function call
279  void clear() {
280  predecessors.clear();
281  distances.clear();
282  }
283 
284 
285  // used when multiple goals
286  std::deque<Path> get_paths(
287  const G &graph,
288  V source,
289  std::vector< V > &targets,
290  bool only_cost) const {
291  log << std::string(__FUNCTION__) << "\n";
292  std::deque<Path> paths;
293  for (const auto target : targets) {
294  paths.push_back(Path(
295  graph,
296  source, target,
298  only_cost, true));
299  }
300  return paths;
301  }
302 
303 
304 
306 
307  std::vector< V > predecessors;
308  std::vector< double > distances;
309 
311 };
312 
313 #endif // INCLUDE_BELLMAN_FORD_PGR_BELLMAN_FORD_HPP_
pgrouting::Pgr_messages
Definition: pgr_messages.h:39
interruption.h
Path
Definition: basePath_SSEC.hpp:47
pgr_base_graph.hpp
pgr_messages.h
Pgr_bellman_ford::bellman_ford
Path bellman_ford(G &graph, int64_t start_vertex, int64_t end_vertex, bool only_cost=false)
BellmanFord 1 to 1.
Definition: pgr_bellman_ford.hpp:62
pgrouting::Pgr_messages::log
std::ostringstream log
Stores the hint information.
Definition: pgr_messages.h:81
Pgr_bellman_ford::bellman_ford
std::deque< Path > bellman_ford(G &graph, int64_t start_vertex, const std::vector< int64_t > &end_vertex, bool only_cost=false)
BellmanFord 1 to many.
Definition: pgr_bellman_ford.hpp:97
Pgr_bellman_ford::bellman_ford
std::deque< Path > bellman_ford(G &graph, const std::vector< pgr_combination_t > &combinations, bool only_cost=false)
Definition: pgr_bellman_ford.hpp:185
Pgr_bellman_ford
Definition: pgr_bellman_ford.hpp:53
pgrouting::alphashape::E
boost::graph_traits< BG >::edge_descriptor E
Definition: pgr_alphaShape.h:57
pgr_combination_t
Definition: pgr_combination_t.h:43
Pgr_bellman_ford::clear
void clear()
Definition: pgr_bellman_ford.hpp:279
Pgr_bellman_ford::V
G::V V
Definition: pgr_bellman_ford.hpp:55
Pgr_bellman_ford::bellman_ford_1_to_1
bool bellman_ford_1_to_1(G &graph, V source)
Call to BellmanFord 1 source to 1 target.
Definition: pgr_bellman_ford.hpp:224
Pgr_bellman_ford::bellman_ford
std::deque< Path > bellman_ford(G &graph, const std::vector< int64_t > &start_vertex, const std::vector< int64_t > &end_vertex, bool only_cost=false)
Definition: pgr_bellman_ford.hpp:158
Pgr_bellman_ford::distances
std::vector< double > distances
Definition: pgr_bellman_ford.hpp:308
Pgr_bellman_ford::predecessors
std::vector< V > predecessors
Definition: pgr_bellman_ford.hpp:307
pgrouting::alphashape::G
graph::Pgr_base_graph< BG, XY_vertex, Basic_edge > G
Definition: pgr_alphaShape.h:56
Pgr_bellman_ford::bellman_ford
std::deque< Path > bellman_ford(G &graph, const std::vector< int64_t > &start_vertex, int64_t end_vertex, bool only_cost=false)
Definition: pgr_bellman_ford.hpp:137
pgrouting::alphashape::V
boost::graph_traits< BG >::vertex_descriptor V
Definition: pgr_alphaShape.h:58
Pgr_bellman_ford::get_paths
std::deque< Path > get_paths(const G &graph, V source, std::vector< V > &targets, bool only_cost) const
Definition: pgr_bellman_ford.hpp:286
Pgr_bellman_ford::bellman_ford_1_to_many
bool bellman_ford_1_to_many(G &graph, V source)
Call to BellmanFord 1 source to many targets.
Definition: pgr_bellman_ford.hpp:251
Pgr_bellman_ford::E
G::E E
Definition: pgr_bellman_ford.hpp:56
basePath_SSEC.hpp