49#include <lal/basic_types.hpp>
50#include <lal/linear_arrangement.hpp>
51#include <lal/graphs/free_tree.hpp>
52#include <lal/graphs/rooted_tree.hpp>
53#include <lal/detail/array.hpp>
63 bool ensure_root_is_returned,
64 bool free_tree_plus_root =
65 ensure_root_is_returned and
66 std::is_same_v<tree_t, graphs::free_tree>
71 std::pair<tree_t, node>,
74from_edge_list_to_tree(std::stringstream& ss)
noexcept
76 static_assert(std::is_base_of_v<graphs::tree, tree_t>);
82 uint64_t max_node_idx = 0;
88 while (ss >> curly_bracket) {
89 ss >> u >> v >> curly_bracket;
90 max_node_idx = std::max(max_node_idx, u);
91 max_node_idx = std::max(max_node_idx, v);
102 while (ss >> curly_bracket) {
103 ss >> u >> v >> curly_bracket;
104 t.add_edge_bulk(u,v);
106 t.finish_bulk_add_complete();
108 if constexpr (std::is_same_v<tree_t, graphs::rooted_tree>) {
117 assert(not t.has_root());
122 if (t.get_in_degree(w) == 0) {
129 assert(t.is_rooted_tree());
138 if constexpr (free_tree_plus_root) {
139 static_assert(std::is_same_v<tree_t, graphs::free_tree>);
162template <
class graph_t>
167 uint64_t max_vertex_index = 0;
169 max_vertex_index = std::max(max_vertex_index, e.first);
170 max_vertex_index = std::max(max_vertex_index, e.second);
172 const uint64_t num_nodes = 1 + max_vertex_index;
173 graph_t g(num_nodes);
174 g.set_edges(
edge_list, normalize, check);
189template <
class graph_t>
191(
const head_vector& hv,
const bool normalize,
const bool check)
194 const uint64_t n = hv.size();
196 for (uint64_t i = 0; i < n; ++i) {
201 g.add_edge_bulk(hv[i] - 1, i);
204 if constexpr (std::is_base_of_v<graphs::tree, graph_t>) {
205 g.finish_bulk_add_complete(normalize, check);
208 g.finish_bulk_add(normalize, check);
223 bool ensure_root_is_returned,
224 bool free_tree_plus_root =
225 ensure_root_is_returned and
226 std::is_same_v<tree_t, graphs::free_tree>
231 std::pair<tree_t, node>,
236 static_assert(std::is_base_of_v<graphs::tree, tree_t>);
238 uint64_t num_nodes = 0;
242 while (ss >> u) { ++num_nodes; }
250 node r = num_nodes + 1;
253 uint64_t num_edges_added = 0;
271 t.add_edge_bulk(u - 1, i);
282 assert(r < num_nodes);
284 assert(num_edges_added == num_nodes - 1);
287 t.finish_bulk_add_complete();
288 if constexpr (std::is_same_v<tree_t, graphs::rooted_tree>) {
291 assert(t.is_rooted_tree());
300 if constexpr (free_tree_plus_root) {
301 static_assert(std::is_same_v<tree_t, graphs::free_tree>);
302 return {std::move(t), r};
320 bool is_rooted = std::is_base_of_v<graphs::rooted_tree, tree_t>
326 std::pair<graphs::free_tree, node>
329(
const head_vector& hv,
const bool normalize,
const bool check)
332 static_assert(std::is_base_of_v<graphs::tree, tree_t>);
334 if (hv.size() == 0) {
335 if constexpr (is_rooted) {
342 if (hv.size() == 1) {
347 if constexpr (is_rooted) {
355 const uint64_t num_nodes = hv.size();
361 node r = num_nodes + 1;
364 uint64_t num_edges_added = 0;
367 for (uint64_t i = 0; i < num_nodes; ++i) {
381 t.add_edge_bulk(hv[i] - 1, i);
391 assert(r < num_nodes);
393 assert(num_edges_added == num_nodes - 1);
396 t.finish_bulk_add_complete(normalize, check);
398 if constexpr (is_rooted) {
401 assert(t.is_rooted_tree());
411 return {std::move(t), r};
422template <
class arrangement_t>
428 assert(t.is_rooted_tree());
431 const uint64_t n = t.get_num_nodes();
434 const node u = arr[p];
435 if (t.get_root() == u) {
439 const node_t parent = t.get_in_neighbors(u)[0];
440 hv[*p] = arr[parent] + 1;
454template <
class arrangement_t>
494template <
class tree_t>
497 const uint64_t *
const L,
499 const bool normalize,
504 static_assert(std::is_base_of_v<graphs::tree, tree_t>);
517 std::size_t stack_it = 0;
520 root_candidates[0] = 1;
521 for (
node i = 2; i <= n; ++i) {
523 if (root_candidates[stack_it] + 2 > L[i]) {
524 stack_it = L[i] - 2 + 1;
528 const node r = root_candidates[stack_it];
531 const auto [u,v] = (r == 0 ?
edge(r, i - 1) :
edge(r - 1, i - 1));
532 t.add_edge_bulk(u, v);
537 assert(stack_it == L[i]);
539 root_candidates[stack_it] = i;
542 if constexpr (std::is_base_of_v<graphs::rooted_tree, tree_t>) {
546 t.finish_bulk_add_complete(normalize, check);
580template <
class tree_t>
583 const uint64_t *
const L,
585 const bool normalize,
590 static_assert(std::is_base_of_v<graphs::tree, tree_t>);
601 std::size_t stack_it = 0;
604 std::size_t edge_it = 0;
608 root_candidates[0] = 1;
609 for (
node i = 2; i <= n; ++i) {
611 if (root_candidates[stack_it] + 2 > L[i]) {
612 stack_it = L[i] - 2 + 1;
616 const node r = root_candidates[stack_it];
619 const edge e = (r == 0 ?
edge(r, i - 1) :
edge(r - 1, i - 1));
621 ++vertex_degrees[e.first];
622 ++vertex_degrees[e.second];
627 assert(stack_it == L[i]);
629 root_candidates[stack_it] = i;
633 assert(edge_it == n - 1);
637 for (
node u = 0; u < n; ++u) {
638 if constexpr (std::is_base_of_v<graphs::free_tree, tree_t>) {
639 t.reserve_degree(u, vertex_degrees[u]);
642 t.reserve_out_degree(u, vertex_degrees[u] - (u != 0));
643 t.reserve_in_degree(u, u != 0);
647 t.add_edge_bulk(e.first, e.second);
650 if constexpr (std::is_base_of_v<graphs::rooted_tree, tree_t>) {
656 if constexpr (std::is_base_of_v<graphs::rooted_tree, tree_t>) {
657 assert(t.has_root());
661 t.finish_bulk_add_complete(normalize, check);
690template <
class tree_t>
693 const uint64_t *
const L,
695 const bool normalize,
700 static_assert(std::is_base_of_v<graphs::tree, tree_t>);
711template <
class tree_t>
714 const std::vector<uint64_t>& L,
716 const bool normalize,
721 static_assert(std::is_base_of_v<graphs::tree, tree_t>);
730template <
class tree_t>
733 const std::vector<uint64_t>& L,
735 const bool normalize,
740 static_assert(std::is_base_of_v<graphs::tree, tree_t>);
749template <
class tree_t>
751 const std::vector<uint64_t>& L,
753 const bool normalize,
758 static_assert(std::is_base_of_v<graphs::tree, tree_t>);
778 const uint64_t *
const seq,
780 const bool normalize,
786 const uint64_t L = n - 2;
788 for (uint64_t i = 0; i < L; ++i) {
789 degree[ seq[i] ] += 1;
799 for (uint64_t v = 0; v < L; ++v) {
800 const auto value = seq[v];
801 bool node_found =
false;
803 while (w < n and not node_found) {
804 if (degree[w] == 1) {
818 for (
node w = 0; w < n; ++w) {
819 if (degree[w] == 1) {
847 const std::vector<uint64_t>& seq,
849 const bool normalize,
Free tree graph class.
Definition free_tree.hpp:60
free_tree & add_edge_bulk(const node s, const node t) noexcept
Adds an edge to the tree.
void finish_bulk_add_complete(const bool norm=true, const bool check=true) noexcept
Completes the inner structure of the tree after adding edges in bulk.
Rooted tree graph class.
Definition rooted_tree.hpp:109
graph_t from_edge_list_to_graph(const edge_list &edge_list, const bool normalize, const bool check) noexcept
Converts an edge list into a graph.
Definition conversions.hpp:164
head_vector from_tree_to_head_vector(const graphs::rooted_tree &t, const arrangement_t &arr) noexcept
Constructs the head vector representation of a tree.
Definition conversions.hpp:424
tree_t from_level_sequence_to_tree_large(const uint64_t *const L, const uint64_t n, const bool normalize, const bool check) noexcept
Converts the level sequence of a tree into a graph structure.
Definition conversions.hpp:582
tree_t from_level_sequence_to_tree_small(const uint64_t *const L, const uint64_t n, const bool normalize, const bool check) noexcept
Converts the level sequence of a tree into a graph structure.
Definition conversions.hpp:496
graph_t from_head_vector_to_graph(const head_vector &hv, const bool normalize, const bool check) noexcept
Transforms a head vector in a directed graph.
Definition conversions.hpp:191
graphs::free_tree from_Prufer_sequence_to_ftree(const uint64_t *const seq, const uint64_t n, const bool normalize, const bool check) noexcept
Converts the Prüfer sequence of a labelled tree into a tree structure.
Definition conversions.hpp:777
std::conditional_t< free_tree_plus_root, std::pair< tree_t, node >, tree_t > from_head_vector_to_tree(std::stringstream &ss) noexcept
Transforms a head vector in a tree.
Definition conversions.hpp:234
tree_t from_level_sequence_to_tree(const uint64_t *const L, const uint64_t n, const bool normalize, const bool check) noexcept
Converts the level sequence of a tree into a graph structure.
Definition conversions.hpp:692
@ num_nodes
Number of nodes of the tree.
Main namespace of the library.
Definition basic_types.hpp:48
std::vector< uint64_t > head_vector
See Head vector page for further details.
Definition basic_types.hpp:58
std::pair< node, node > edge
See Edge page for further details.
Definition basic_types.hpp:56
std::vector< edge > edge_list
See Edge list page for further details.
Definition basic_types.hpp:60
uint64_t node
Node type. See Node / Vertex page for further details.
Definition basic_types.hpp:51
Wrapper of a C array for automatic deallocation of memory.
Definition array.hpp:59
Typesafe node type.
Definition basic_types.hpp:70
Typesafe position type.
Definition basic_types.hpp:244