25 #ifndef INCLUDE_SPANNINGTREE_PGR_MST_HPP_
26 #define INCLUDE_SPANNINGTREE_PGR_MST_HPP_
32 #include <boost/graph/connected_components.hpp>
33 #include <boost/graph/filtered_graph.hpp>
50 typedef typename G::B_G
B_G;
53 typedef typename G::E_i
E_i;
65 std::vector<pgr_mst_rt>
70 std::vector<pgr_mst_rt>
75 std::vector<pgr_mst_rt>
80 std::vector<pgr_mst_rt>
mst(
const G &graph) {
95 std::vector<int64_t> roots,
109 std::vector<int64_t> roots,
123 std::vector<int64_t> roots,
169 template <
typename T>
174 std::vector<pgr_mst_rt> results;
176 std::vector<double> agg_cost(graph.num_vertices(), 0);
177 std::vector<int64_t> depth(graph.num_vertices(), 0);
178 int64_t root(p_root);
180 for (
const auto edge : order) {
181 auto u = graph.source(
edge);
182 auto v = graph.target(
edge);
183 if (depth[u] == 0 && depth[v] != 0) {
188 if (
m_suffix !=
"" && depth[u] == 0 && depth[v] == 0) {
189 if (!
m_roots.empty() && graph[u].id != root) std::swap(u, v);
190 if (
m_roots.empty() && graph[u].id != component) std::swap(u, v);
191 if (!p_root && graph[u].
id > graph[v].
id) std::swap(u, v);
193 root = p_root? p_root: graph[u].id;
204 agg_cost[v] = agg_cost[u] + graph[
edge].cost;
205 depth[v] = depth[u] == -1? 1 : depth[u] + 1;
235 auto num_comps = boost::connected_components(
241 for (
const auto v : boost::make_iterator_range(vertices(graph.graph))) {
249 std::vector<pgr_mst_rt>
254 std::vector<pgr_mst_rt>
256 boost::filtered_graph<B_G, InSpanning, boost::keep_all>
258 std::vector<E> visited_order;
262 CHECK_FOR_INTERRUPTS();
264 boost::depth_first_search(mstGraph, visitor(dfs_visitor(visited_order)));
265 }
catch (boost::exception
const& ex) {
268 }
catch (std::exception &e) {
279 std::vector<pgr_mst_rt>
281 boost::filtered_graph<B_G, InSpanning, boost::keep_all>
287 std::vector<pgr_mst_rt> results;
288 for (
const auto root :
m_roots) {
289 std::vector<E> visited_order;
292 if (graph.has_vertex(root)) {
294 CHECK_FOR_INTERRUPTS();
296 boost::depth_first_search(
298 visitor(dfs_visitor(graph.get_V(root), visited_order))
299 .root_vertex(graph.get_V(root)));
302 }
catch (boost::exception
const& ex) {
305 }
catch (std::exception &e) {
311 auto result =
get_results(visited_order, root, graph);
312 results.insert(results.end(), result.begin(), result.end());
314 results.push_back({root, 0, root, -1, 0.0, 0.0});
321 std::vector<pgr_mst_rt>
323 std::vector<pgr_mst_rt> results;
327 boost::filtered_graph<B_G, InSpanning, boost::keep_all>
332 std::vector<int64_t> roots;
340 for (
auto root : roots) {
341 std::vector<E> visited_order;
342 if (graph.has_vertex(root)) {
343 boost::breadth_first_search(
mst,
345 visitor(bfs_visitor(visited_order)));
347 auto tree_results =
get_results(visited_order, root, graph);
348 results.insert(results.end(), tree_results.begin(), tree_results.end());
350 results.push_back({root, 0, root, -1, 0.0, 0.0});
353 CHECK_FOR_INTERRUPTS();
361 for (boost::tie(ei, ei_end) = edges(graph.graph); ei != ei_end; ++ei)
370 #endif // INCLUDE_SPANNINGTREE_PGR_MST_HPP_