LAL: Linear Arrangement Library 23.01.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 - 2023
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 (lalemany@cs.upc.edu)
28 * LARCA (Laboratory for Relational Algorithmics, Complexity and Learning)
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 * LARCA (Laboratory for Relational Algorithmics, Complexity and Learning)
35 * CQL (Complexity and Quantitative Linguistics Lab)
36 * Office S124, 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 <functional>
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(const tree_t& t, const node u, const node v, uint64_t * const sizes)
75noexcept
76{
77 sizes[v] = 1;
78
79 if constexpr (std::is_base_of_v<graphs::rooted_tree, tree_t>) {
80 for (const node w : t.get_out_neighbours(v)) {
81 if (w == u) { continue; }
82 get_size_subtrees(t, v, w, sizes);
83 sizes[v] += sizes[w];
84 }
85 for (const node w : t.get_in_neighbours(v)) {
86 if (w == u) { continue; }
87 get_size_subtrees(t, v, w, sizes);
88 sizes[v] += sizes[w];
89 }
90 }
91 else {
92 for (const node w : t.get_neighbours(v)) {
93 if (w == u) { continue; }
94 get_size_subtrees(t, v, w, sizes);
95 sizes[v] += sizes[w];
96 }
97 }
98}
99
111template <
112 class tree_t,
113 std::enable_if_t< std::is_base_of_v<graphs::tree, tree_t>, bool> = true
114>
115void get_size_subtrees(const tree_t& t, node r, uint64_t * const sizes)
116noexcept
117{
118#if defined DEBUG
119 assert(sizes != nullptr);
120#endif
121 get_size_subtrees(t, t.get_num_nodes(), r, sizes);
122}
123
148template <
149 class tree_t,
150 typename iterator_t,
151 std::enable_if_t<
152 std::is_base_of_v<graphs::tree, tree_t>
153 and is_pointer_iterator_v<edge_size, iterator_t>,
154 bool
155 > = true
156>
158(const tree_t& t, const uint64_t n, const node u, const node v, iterator_t& it)
159noexcept
160{
161 uint64_t s = 1;
162 if constexpr (std::is_base_of_v<graphs::rooted_tree, tree_t>) {
163 for (const node w : t.get_out_neighbours(v)) {
164 if (w == u) { continue; }
165 s += calculate_bidirectional_sizes(t,n, v, w, it);
166 }
167 for (const node w : t.get_in_neighbours(v)) {
168 if (w == u) { continue; }
169 s += calculate_bidirectional_sizes(t,n, v, w, it);
170 }
171 }
172 else {
173 for (const node w : t.get_neighbours(v)) {
174 if (w == u) { continue; }
175 s += calculate_bidirectional_sizes(t,n, v, w, it);
176 }
177 }
178
179 *it++ = {edge(u,v), s};
180 *it++ = {edge(v,u), n - s};
181 return s;
182}
183
217template <
218 class tree_t,
219 typename iterator_t,
220 std::enable_if_t<
221 std::is_base_of_v<graphs::tree, tree_t>
222 and is_pointer_iterator_v<edge_size, iterator_t>,
223 bool
224 > = true
225>
227(const tree_t& t, const uint64_t n, const node x, iterator_t it)
228noexcept
229{
230 if constexpr (std::is_base_of_v<graphs::rooted_tree, tree_t>) {
231 for (const node y : t.get_out_neighbours(x)) {
232 calculate_bidirectional_sizes(t,n, x, y, it);
233 }
234 for (const node y : t.get_in_neighbours(x)) {
235 calculate_bidirectional_sizes(t,n, x, y, it);
236 }
237 }
238 else {
239 for (const node y : t.get_neighbours(x)) {
240 calculate_bidirectional_sizes(t,n, x, y, it);
241 }
242 }
243}
244
245} // -- namespace detail
246} // -- 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
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:158
Main namespace of the library.
Definition: basic_types.hpp:50
std::pair< node, node > edge
See Edge page for further details.
Definition: basic_types.hpp:58
uint64_t node
Node type. See Node / Vertex page for further details.
Definition: basic_types.hpp:53