LAL: Linear Arrangement Library 24.10.00
A library focused on algorithms on linear arrangements of graphs.
Loading...
Searching...
No Matches
connected_components_compute.hpp
1/*********************************************************************
2 *
3 * Linear Arrangement Library - A library that implements a collection
4 * algorithms for linear arrangments of graphs.
5 *
6 * Copyright (C) 2019 - 2024
7 *
8 * This file is part of Linear Arrangement Library. The full code is available
9 * at:
10 * https://github.com/LAL-project/linear-arrangement-library.git
11 *
12 * Linear Arrangement Library is free software: you can redistribute it
13 * and/or modify it under the terms of the GNU Affero General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * Linear Arrangement Library is distributed in the hope that it will be
18 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Affero General Public License for more details.
21 *
22 * You should have received a copy of the GNU Affero General Public License
23 * along with Linear Arrangement Library. If not, see <http://www.gnu.org/licenses/>.
24 *
25 * Contact:
26 *
27 * LluĂ­s Alemany Puig (lluis.alemany.puig@upc.edu)
28 * LQMC (Quantitative, Mathematical, and Computational Linguisitcs)
29 * CQL (Complexity and Quantitative Linguistics Lab)
30 * Jordi Girona St 1-3, Campus Nord UPC, 08034 Barcelona. CATALONIA, SPAIN
31 * Webpage: https://cqllab.upc.edu/people/lalemany/
32 *
33 * Ramon Ferrer i Cancho (rferrericancho@cs.upc.edu)
34 * LQMC (Quantitative, Mathematical, and Computational Linguisitcs)
35 * CQL (Complexity and Quantitative Linguistics Lab)
36 * Office 220, Omega building
37 * Jordi Girona St 1-3, Campus Nord UPC, 08034 Barcelona. CATALONIA, SPAIN
38 * Webpage: https://cqllab.upc.edu/people/rferrericancho/
39 *
40 ********************************************************************/
41
42#pragma once
43
44// lal includes
45#include <lal/properties/connected_components.hpp>
46#include <lal/detail/graphs/traversal.hpp>
47
48namespace lal {
49namespace detail {
50
51template <bool full_structure, class graph_t>
52[[nodiscard]] std::conditional_t<
53 full_structure,
54 properties::connected_components<graph_t>,
55 std::vector<graph_t>
56>
57connected_components(const graph_t& g)
58noexcept
59{
60 const auto n = g.get_num_nodes();
61 BFS bfs(g);
62 bfs.set_use_rev_edges(true);
63
64 std::unordered_map<node, node> map_nodes_to_current_cc;
65 std::vector<node> nodes_current_cc;
66 std::size_t num_ccs = 0;
67
68 properties::connected_components<graph_t> all_ccs_full;
69 std::vector<graph_t> all_ccs_simple;
70
71 if constexpr (full_structure) {
72 all_ccs_full.init(n);
73 }
74
75 bfs.set_process_current(
76 [&](const auto&, node u) {
77 map_nodes_to_current_cc.insert({u, map_nodes_to_current_cc.size()});
78 nodes_current_cc.push_back(u);
79 if constexpr (full_structure) {
80 all_ccs_full.set_node_cc(u, num_ccs);
81 }
82 }
83 );
84
85 for (node u = 0; u < n; ++u) {
86 if (bfs.node_was_visited(u)) { continue; }
87
88 nodes_current_cc.clear();
89 nodes_current_cc.reserve(n);
90 map_nodes_to_current_cc.clear();
91 map_nodes_to_current_cc.reserve(n);
92
93 bfs.start_at(u);
94 graph_t cc(nodes_current_cc.size());
95 for (node v : nodes_current_cc) {
96
97 if constexpr (std::is_base_of_v<graphs::directed_graph, graph_t>) {
98 for (node w : g.get_out_neighbors(v)) {
99 if (v < w) {
100 cc.add_edge_bulk(
101 map_nodes_to_current_cc[v],
102 map_nodes_to_current_cc[w]
103 );
104 }
105 }
106 for (node w : g.get_in_neighbors(v)) {
107 if (v < w) {
108 cc.add_edge_bulk(
109 map_nodes_to_current_cc[w],
110 map_nodes_to_current_cc[v]
111 );
112 }
113 }
114 }
115 else if constexpr (std::is_base_of_v<graphs::undirected_graph, graph_t>) {
116 for (node w : g.get_neighbors(v)) {
117 if (v < w) {
118 cc.add_edge_bulk(
119 map_nodes_to_current_cc[v],
120 map_nodes_to_current_cc[w]
121 );
122 }
123 }
124 }
125 }
126
127 if constexpr (full_structure) {
128 all_ccs_full.add_graph( std::move(cc) );
129
130 for (node w : nodes_current_cc) {
131 all_ccs_full.set_label_graph_node_to_cc_node
132 (w, map_nodes_to_current_cc[w]);
133 all_ccs_full.set_label_cc_node_to_graph_node
134 (num_ccs, map_nodes_to_current_cc[w], w);
135 }
136 }
137 else {
138 all_ccs_simple.push_back( std::move(cc) );
139 }
140
141 ++num_ccs;
142 }
143
144 if constexpr (full_structure) {
145 return all_ccs_full;
146 }
147 else {
148 return all_ccs_simple;
149 }
150}
151
152} // -- namespace detail
153} // -- namespace lal
Main namespace of the library.
Definition basic_types.hpp:48
uint64_t node
Node type. See Node / Vertex page for further details.
Definition basic_types.hpp:51