LAL: Linear Arrangement Library 24.10.00
A library focused on algorithms on linear arrangements of graphs.
Loading...
Searching...
No Matches
size_subtrees.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// C++ includes
45#if defined DEBUG
46#include <cassert>
47#endif
48#include <tuple>
49
50// lal includes
51#include <lal/graphs/rooted_tree.hpp>
52#include <lal/graphs/free_tree.hpp>
53#include <lal/detail/type_traits/is_pointer_iterator.hpp>
54#include <lal/detail/pairs_utils.hpp>
55
56namespace lal {
57namespace detail {
58
69template <
70 class tree_t,
71 std::enable_if_t< std::is_base_of_v<graphs::tree, tree_t>, bool> = true
72>
74(
75 const tree_t& t,
76 const node u,
77 const node v,
78 uint64_t * const sizes
79)
80noexcept
81{
82 sizes[v] = 1;
83
84 if constexpr (std::is_base_of_v<graphs::rooted_tree, tree_t>) {
85 for (const node w : t.get_out_neighbors(v)) {
86 if (w == u) { continue; }
87 get_size_subtrees(t, v, w, sizes);
88 sizes[v] += sizes[w];
89 }
90 for (const node w : t.get_in_neighbors(v)) {
91 if (w == u) { continue; }
92 get_size_subtrees(t, v, w, sizes);
93 sizes[v] += sizes[w];
94 }
95 }
96 else {
97 for (const node w : t.get_neighbors(v)) {
98 if (w == u) { continue; }
99 get_size_subtrees(t, v, w, sizes);
100 sizes[v] += sizes[w];
101 }
102 }
103}
104
116template <
117 class tree_t,
118 std::enable_if_t< std::is_base_of_v<graphs::tree, tree_t>, bool> = true
119>
121 const tree_t& t,
122 const node r,
123 uint64_t * const sizes
124)
125noexcept
126{
127#if defined DEBUG
128 assert(sizes != nullptr);
129#endif
130 get_size_subtrees(t, t.get_num_nodes(), r, sizes);
131}
132
157template <
158 class tree_t,
159 typename iterator_t,
160 std::enable_if_t<
161 std::is_base_of_v<graphs::tree, tree_t>
163 bool
164 > = true
165>
166[[nodiscard]]
168(
169 const tree_t& t,
170 const uint64_t n,
171 const node u,
172 const node v,
173 iterator_t& it
174)
175noexcept
176{
177 uint64_t s = 1;
178 if constexpr (std::is_base_of_v<graphs::rooted_tree, tree_t>) {
179 for (const node w : t.get_out_neighbors(v)) {
180 if (w == u) { continue; }
181 s += calculate_bidirectional_sizes(t,n, v, w, it);
182 }
183 for (const node w : t.get_in_neighbors(v)) {
184 if (w == u) { continue; }
185 s += calculate_bidirectional_sizes(t,n, v, w, it);
186 }
187 }
188 else {
189 for (const node w : t.get_neighbors(v)) {
190 if (w == u) { continue; }
191 s += calculate_bidirectional_sizes(t,n, v, w, it);
192 }
193 }
194
195 *it++ = {edge(u,v), s};
196 *it++ = {edge(v,u), n - s};
197 return s;
198}
199
233template <
234 class tree_t,
235 typename iterator_t,
236 std::enable_if_t<
237 std::is_base_of_v<graphs::tree, tree_t>
239 bool
240 > = true
241>
243 const tree_t& t,
244 const uint64_t n,
245 const node x,
246 iterator_t it
247)
248noexcept
249{
250 if constexpr (std::is_base_of_v<graphs::rooted_tree, tree_t>) {
251 for (const node y : t.get_out_neighbors(x)) {
252 std::ignore = calculate_bidirectional_sizes(t,n, x, y, it);
253 }
254 for (const node y : t.get_in_neighbors(x)) {
255 std::ignore = calculate_bidirectional_sizes(t,n, x, y, it);
256 }
257 }
258 else {
259 for (const node y : t.get_neighbors(x)) {
260 std::ignore = calculate_bidirectional_sizes(t,n, x, y, it);
261 }
262 }
263}
264
265} // -- namespace detail
266} // -- namespace lal
void get_size_subtrees(const tree_t &t, const node u, const node v, uint64_t *const sizes) noexcept
Calculate the size of every subtree of the tree t.
Definition size_subtrees.hpp:74
constexpr bool is_pointer_iterator_v
Shorthand for is_pointer_iterator.
Definition is_pointer_iterator.hpp:68
uint64_t calculate_bidirectional_sizes(const tree_t &t, const uint64_t n, const node u, const node v, iterator_t &it) noexcept
Calculates the values for the edges reachable from in the subtree .
Definition size_subtrees.hpp:168
Main namespace of the library.
Definition basic_types.hpp:48
std::pair< node, node > edge
See Edge page for further details.
Definition basic_types.hpp:56
uint64_t node
Node type. See Node / Vertex page for further details.
Definition basic_types.hpp:51