PGROUTING  3.2
pgr_components.cpp
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 
3 Copyright (c) 2015 pgRouting developers
5 
6 Copyright (c) 2017 Maoguang Wang
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 
28 
29 #include <boost/config.hpp>
30 #include <boost/graph/adjacency_list.hpp>
31 #include <boost/graph/connected_components.hpp>
32 #include <boost/graph/strong_components.hpp>
33 #include <boost/graph/biconnected_components.hpp>
34 
35 #include <vector>
36 #include <map>
37 #include <utility>
38 #include <algorithm>
39 
42 
43 namespace pgrouting {
44 namespace algorithms {
45 
46 std::vector<pgr_components_rt>
49  // perform the algorithm
50  std::vector<V> components(num_vertices(graph.graph));
51  size_t num_comps;
52  /* abort in case of an interruption occurs (e.g. the query is being cancelled) */
53  CHECK_FOR_INTERRUPTS();
54  try {
55  num_comps = boost::connected_components(graph.graph, &components[0]);
56  } catch (...) {
57  throw;
58  }
59 
60  // get the results
61  std::vector< std::vector< int64_t > > results(num_comps);
62  for (auto vd : boost::make_iterator_range(vertices(graph.graph))) {
63  results[components[vd]].push_back(graph[vd].id);
64  }
65 
66  return detail::componentsResult(results);
67 }
68 
70 std::vector<pgr_components_rt>
72  pgrouting::DirectedGraph &graph) {
74  // perform the algorithm
75  std::vector<V> components(num_vertices(graph.graph));
76  size_t num_comps;
77  /* abort in case of an interruption occurs (e.g. the query is being cancelled) */
78  CHECK_FOR_INTERRUPTS();
79  try {
80  num_comps = boost::strong_components(
81  graph.graph,
82  boost::make_iterator_property_map(components.begin(),
83  get(boost::vertex_index, graph.graph)));
84  } catch (...) {
85  throw;
86  }
87 
88  // get the results
89  std::vector< std::vector< int64_t > > results(num_comps);
90  for (auto vd : boost::make_iterator_range(vertices(graph.graph))) {
91  results[components[vd]].push_back(graph[vd].id);
92  }
93 
94  return detail::componentsResult(results);
95 }
96 
97 
98 
100 std::vector<pgr_components_rt>
104  using E = G::E;
105  using Edge_map = std::map< E, size_t >;
106 
107  // perform the algorithm
108  Edge_map bicmp_map;
109  boost::associative_property_map<Edge_map> bimap(bicmp_map);
110  size_t num_comps;
111  try {
112  num_comps = biconnected_components(graph.graph, bimap);
113  } catch (...) {
114  throw;
115  }
116 
117  std::vector< std::vector< int64_t > > results(num_comps);
118  for (auto ed : boost::make_iterator_range(edges(graph.graph))) {
119  results[bimap[ed]].push_back(graph[ed].id);
120  }
121 
122  return detail::componentsResult(results);
123 }
124 
129  using V = G::V;
130  /* abort in case of an interruption occurs (e.g. the query is being cancelled) */
131  CHECK_FOR_INTERRUPTS();
132 
133  // perform the algorithm
134  std::vector<V> art_points;
135  try {
136  boost::articulation_points(graph.graph, std::back_inserter(art_points));
137  } catch (...) {
138  throw;
139  }
140 
141  // get the results
142  Identifiers<int64_t> results;
143  for (const auto v : art_points) {
144  results += graph[v].id;
145  }
146 
147  return results;
148 }
149 
164  using V = G::V;
165  using EO_i = G::EO_i;
166 
167  Identifiers<int64_t> bridge_edges;
168  Identifiers<int64_t> processed_edges;
169  std::vector<V> components(num_vertices(graph.graph));
170  size_t ini_comps;
171  /* abort in case of an interruption occurs (e.g. the query is being cancelled) */
172  CHECK_FOR_INTERRUPTS();
173  try {
174  ini_comps = boost::connected_components(graph.graph, &components[0]);
175  } catch (...) {
176  throw;
177  }
178  /* abort in case of an interruption occurs (e.g. the query is being cancelled) */
179  CHECK_FOR_INTERRUPTS();
180  std::vector<V> art_points;
181  try {
182  boost::articulation_points(graph.graph, std::back_inserter(art_points));
183  } catch (...) {
184  throw;
185  }
186 
187  for (auto v : boost::make_iterator_range(vertices(graph.graph))) {
188  if (graph.out_degree(v) == 1) {
189  art_points.push_back(v);
190  }
191  }
192 
193  for (const auto u : art_points) {
194  for (const auto v : art_points) {
195  /*
196  * skip when the vertices are the same and do half the work
197  */
198  if (u < v) continue;
199  auto p = boost::edge(u, v, graph.graph);
200 
201  /*
202  * skip when there is no edge (u, v) on the graph
203  */
204  if (!p.second) continue;
205  auto edge = p.first;
206  auto id = graph[edge].id;
207 
208  /*
209  * Skip when the edge has already being processed
210  */
211  if (processed_edges.has(id)) continue;
212 
213  /*
214  * Processing edge
215  */
216  processed_edges += id;
217 
218 
219  /*
220  * At least one edge between articulation points u & v
221  */
222  int parallel_count = 0;
223  EO_i ei, ei_end;
224  boost::tie(ei, ei_end) = out_edges(u, graph.graph);
225 
226  for ( ; ei != ei_end; ++ei) {
227  if (target(*ei, graph.graph) == v) ++parallel_count;
228  }
229 
230  if (parallel_count == 1) {
231  // TODO(vicky) filter graph instead of removing edges
232  size_t now_comps;
233  try {
234  boost::remove_edge(edge, graph.graph);
235 
236  now_comps = boost::connected_components(graph.graph, &components[0]);
237 
238  boost::add_edge(boost::source(edge, graph.graph),
239  boost::target(edge, graph.graph),
240  graph.graph);
241  } catch (...) {
242  throw;
243  }
244 
245  if (now_comps > ini_comps) {
246  bridge_edges += id;
247  }
248  }
249  }
250  }
251 
252  return bridge_edges;
253 }
254 
255 } // namespace algorithms
256 } // namespace pgrouting
pgrouting::algorithms::biconnectedComponents
std::vector< pgr_components_rt > biconnectedComponents(pgrouting::UndirectedGraph &graph)
Biconnected Components.
Definition: pgr_components.cpp:101
interruption.h
pgrouting::graph::Pgr_base_graph::graph
G graph
The graph.
Definition: pgr_base_graph.hpp:260
pgrouting::graph::Pgr_base_graph::out_degree
degree_size_type out_degree(int64_t vertex_id) const
get the out-degree of a vertex
Definition: pgr_base_graph.hpp:489
pgrouting::UndirectedGraph
graph::Pgr_base_graph< boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, Basic_vertex, Basic_edge >, Basic_vertex, Basic_edge > UndirectedGraph
Definition: pgr_base_graph.hpp:186
pgrouting::algorithms::articulationPoints
Identifiers< int64_t > articulationPoints(pgrouting::UndirectedGraph &graph)
Articulation Points.
Definition: pgr_components.cpp:126
edge
Definition: trsp.h:41
pgr_components.hpp
pgrouting::algorithms::bridges
Identifiers< int64_t > bridges(pgrouting::UndirectedGraph &graph)
Bridges Bridges are closely related to the concept of articulation vertices, vertices that belong to ...
Definition: pgr_components.cpp:162
pgrouting::alphashape::E
boost::graph_traits< BG >::edge_descriptor E
Definition: pgr_alphaShape.h:57
pgrouting::algorithms::detail::componentsResult
std::vector< pgr_components_rt > componentsResult(std::vector< std::vector< int64_t > > &components)
Definition: componentsResult.cpp:38
pgrouting::algorithms::pgr_connectedComponents
std::vector< pgr_components_rt > pgr_connectedComponents(pgrouting::UndirectedGraph &graph)
works for undirected graph
Definition: pgr_components.cpp:47
Identifiers::has
bool has(const T other) const
true ids() has element
Definition: identifiers.hpp:98
pgrouting::alphashape::G
graph::Pgr_base_graph< BG, XY_vertex, Basic_edge > G
Definition: pgr_alphaShape.h:56
pgrouting::graph::Pgr_base_graph::V
boost::graph_traits< G >::vertex_descriptor V
Definition: pgr_base_graph.hpp:229
pgrouting::graph::Pgr_base_graph
Definition: pgr_base_graph.hpp:168
pgrouting::algorithms::strongComponents
std::vector< pgr_components_rt > strongComponents(pgrouting::DirectedGraph &graph)
Strongly Connected Components Vertex Version.
Definition: pgr_components.cpp:71
pgrouting::alphashape::V
boost::graph_traits< BG >::vertex_descriptor V
Definition: pgr_alphaShape.h:58
pgrouting
Book keeping class for swapping orders between vehicles.
Definition: pgr_alphaShape.cpp:56
identifiers.hpp
Identifiers< int64_t >