PGROUTING  3.2
pgr_edwardMoore.hpp
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: pgr_edwardMoore.hpp
3 Copyright (c) 2019 pgRouting developers
5 Copyright (c) 2019 Gudesa Venkata Sai AKhil
7 ------
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 ********************************************************************PGR-GNU*/
20 
21 #ifndef INCLUDE_BELLMAN_FORD_PGR_EDWARDMOORE_HPP_
22 #define INCLUDE_BELLMAN_FORD_PGR_EDWARDMOORE_HPP_
23 #pragma once
24 
25 #include <limits>
26 #include <algorithm>
27 #include <vector>
28 #include <deque>
29 #include <map>
30 
31 
35 //******************************************
36 
37 namespace pgrouting {
38 namespace functions {
39 
40 template <class G>
42  public:
43  typedef typename G::V V;
44  typedef typename G::E E;
45  typedef typename G::B_G B_G;
46  typedef typename G::EO_i EO_i;
47  typedef typename G::E_i E_i;
48 
49  std::deque<Path> edwardMoore(
50  G &graph,
51  std::vector<int64_t> start_vertex,
52  std::vector<int64_t> end_vertex) {
53  std::deque<Path> paths;
54 
55  for (auto source : start_vertex) {
56  std::deque<Path> result_paths = one_to_many_edwardMoore(
57  graph,
58  source,
59  end_vertex);
60 
61  paths.insert(
62  paths.begin(),
63  std::make_move_iterator(result_paths.begin()),
64  std::make_move_iterator(result_paths.end()));
65  }
66 
67  std::sort(paths.begin(), paths.end(),
68  [](const Path &e1, const Path &e2) -> bool {
69  return e1.end_id() < e2.end_id();
70  });
71  std::stable_sort(paths.begin(), paths.end(),
72  [](const Path &e1, const Path &e2) -> bool {
73  return e1.start_id() < e2.start_id();
74  });
75 
76  return paths;
77  }
78 
79  // preparation for the parallel arrays
80  std::deque<Path> edwardMoore(
81  G &graph,
82  const std::vector<pgr_combination_t> &combinations) {
83  std::deque<Path> paths;
84 
85  // group targets per distinct source
86  std::map< int64_t, std::vector<int64_t> > vertex_map;
87  for (const pgr_combination_t &comb : combinations) {
88  std::map< int64_t, std::vector<int64_t> >::iterator it = vertex_map.find(comb.source);
89  if (it != vertex_map.end()) {
90  it->second.push_back(comb.target);
91  } else {
92  std::vector<int64_t > targets{comb.target};
93  vertex_map[comb.source] = targets;
94  }
95  }
96 
97  for (const auto &start_ends : vertex_map) {
98  std::deque<Path> result_paths = one_to_many_edwardMoore(
99  graph,
100  start_ends.first,
101  start_ends.second);
102 
103  paths.insert(
104  paths.end(),
105  std::make_move_iterator(result_paths.begin()),
106  std::make_move_iterator(result_paths.end()));
107  }
108 
109  std::sort(paths.begin(), paths.end(),
110  [](const Path &e1, const Path &e2) -> bool {
111  return e1.end_id() < e2.end_id();
112  });
113  std::stable_sort(paths.begin(), paths.end(),
114  [](const Path &e1, const Path &e2) -> bool {
115  return e1.start_id() < e2.start_id();
116  });
117 
118  return paths;
119  }
120 
121  private:
123 
124  std::deque<Path> one_to_many_edwardMoore(
125  G &graph,
126  int64_t start_vertex,
127  std::vector<int64_t> end_vertex) {
128  std::deque<Path> paths;
129 
130  if (graph.has_vertex(start_vertex) == false) {
131  return paths;
132  }
133 
134  std::vector<double> current_cost(graph.num_vertices(), std::numeric_limits<double>::infinity());
135  std::vector<bool> isInQ(graph.num_vertices(), false);
136  std::vector<E> from_edge(graph.num_vertices());
137  std::deque<V> dq;
138  DEFAULT_EDGE = from_edge[0];
139 
140  auto bgl_start_vertex = graph.get_V(start_vertex);
141 
142  current_cost[bgl_start_vertex] = 0;
143  isInQ[bgl_start_vertex] = true;
144  dq.push_front(bgl_start_vertex);
145 
146  while (dq.empty() == false) {
147  auto head_vertex = dq.front();
148 
149  dq.pop_front();
150  isInQ[head_vertex] = false;
151 
152  updateVertexCosts(graph, current_cost, isInQ, from_edge, dq, head_vertex);
153  }
154 
155  for (auto target_vertex : end_vertex) {
156  if (graph.has_vertex(target_vertex) == false) {
157  continue;
158  }
159 
160  auto bgl_target_vertex = graph.get_V(target_vertex);
161 
162  if (from_edge[bgl_target_vertex] == DEFAULT_EDGE) {
163  continue;
164  }
165 
166  paths.push_front(
167  getPath(graph, bgl_start_vertex, target_vertex, bgl_target_vertex, from_edge, current_cost));
168  }
169 
170  return paths;
171  }
172 
174  G &graph,
175  V bgl_start_vertex,
176  int64_t target,
177  V bgl_target_vertex,
178  std::vector<E> &from_edge,
179  std::vector<double> &current_cost) {
180  auto current_node = bgl_target_vertex;
181 
182  Path path = Path(graph[bgl_start_vertex].id, graph[current_node].id);
183 
184  path.push_back({target, -1, 0, current_cost[current_node]});
185 
186  do {
187  E e = from_edge[current_node];
188  auto from = graph.source(e);
189 
190  path.push_back({graph[from].id, graph[e].id, graph[e].cost, current_cost[from]});
191 
192  current_node = from;
193  } while (from_edge[current_node] != DEFAULT_EDGE);
194 
195  std::reverse(path.begin(), path.end());
196  return path;
197  }
198 
200  G &graph,
201  std::vector<double> &current_cost,
202  std::vector<bool> &isInQ,
203  std::vector<E> &from_edge,
204  std::deque<V> &dq,
205  V &head_vertex) {
206  /* abort in case of an interruption occurs (e.g. the query is being cancelled) */
207  CHECK_FOR_INTERRUPTS();
208 
209  auto out_edges = boost::out_edges(head_vertex, graph.graph);
210  E e;
211  EO_i out_i;
212  EO_i out_end;
213  V v_source, v_target;
214 
215  for (boost::tie(out_i, out_end) = out_edges;
216  out_i != out_end; ++out_i) {
217  e = *out_i;
218  v_target = graph.target(e);
219  v_source = graph.source(e);
220  double edge_cost = graph[e].cost;
221 
222  if (std::isinf(current_cost[v_target]) || current_cost[v_source] + edge_cost < current_cost[v_target]) {
223  current_cost[v_target] = current_cost[v_source] + edge_cost;
224 
225  from_edge[v_target] = e;
226 
227  if (isInQ[v_target] == false) {
228  dq.push_back(v_target);
229  isInQ[v_target] = true;
230  }
231  }
232  }
233  }
234 };
235 } // namespace functions
236 } // namespace pgrouting
237 
238 #endif // INCLUDE_BELLMAN_FORD_PGR_EDWARDMOORE_HPP_
interruption.h
Path
Definition: basePath_SSEC.hpp:47
Path::push_back
void push_back(Path_t data)
Definition: basePath_SSEC.cpp:52
pgr_base_graph.hpp
Path::end
pthIt end()
Definition: basePath_SSEC.hpp:82
pgrouting::functions::Pgr_edwardMoore::edwardMoore
std::deque< Path > edwardMoore(G &graph, const std::vector< pgr_combination_t > &combinations)
Definition: pgr_edwardMoore.hpp:80
pgrouting::functions::Pgr_edwardMoore
Definition: pgr_edwardMoore.hpp:41
pgrouting::alphashape::E
boost::graph_traits< BG >::edge_descriptor E
Definition: pgr_alphaShape.h:57
pgrouting::functions::Pgr_edwardMoore::EO_i
G::EO_i EO_i
Definition: pgr_edwardMoore.hpp:46
pgr_combination_t
Definition: pgr_combination_t.h:43
pgrouting::functions::Pgr_edwardMoore::one_to_many_edwardMoore
std::deque< Path > one_to_many_edwardMoore(G &graph, int64_t start_vertex, std::vector< int64_t > end_vertex)
Definition: pgr_edwardMoore.hpp:124
pgrouting::functions::Pgr_edwardMoore::B_G
G::B_G B_G
Definition: pgr_edwardMoore.hpp:45
pgrouting::functions::Pgr_edwardMoore::DEFAULT_EDGE
E DEFAULT_EDGE
Definition: pgr_edwardMoore.hpp:122
pgrouting::functions::Pgr_edwardMoore::E_i
G::E_i E_i
Definition: pgr_edwardMoore.hpp:47
pgrouting::functions::Pgr_edwardMoore::edwardMoore
std::deque< Path > edwardMoore(G &graph, std::vector< int64_t > start_vertex, std::vector< int64_t > end_vertex)
Definition: pgr_edwardMoore.hpp:49
pgrouting::alphashape::G
graph::Pgr_base_graph< BG, XY_vertex, Basic_edge > G
Definition: pgr_alphaShape.h:56
pgrouting::functions::Pgr_edwardMoore::V
G::V V
Definition: pgr_edwardMoore.hpp:43
pgrouting::functions::Pgr_edwardMoore::E
G::E E
Definition: pgr_edwardMoore.hpp:44
pgrouting::alphashape::V
boost::graph_traits< BG >::vertex_descriptor V
Definition: pgr_alphaShape.h:58
pgrouting::functions::Pgr_edwardMoore::getPath
Path getPath(G &graph, V bgl_start_vertex, int64_t target, V bgl_target_vertex, std::vector< E > &from_edge, std::vector< double > &current_cost)
Definition: pgr_edwardMoore.hpp:173
pgrouting
Book keeping class for swapping orders between vehicles.
Definition: pgr_alphaShape.cpp:56
Path::begin
pthIt begin()
Definition: basePath_SSEC.hpp:81
pgrouting::functions::Pgr_edwardMoore::updateVertexCosts
void updateVertexCosts(G &graph, std::vector< double > &current_cost, std::vector< bool > &isInQ, std::vector< E > &from_edge, std::deque< V > &dq, V &head_vertex)
Definition: pgr_edwardMoore.hpp:199
basePath_SSEC.hpp