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/data_array.hpp>
54#include <lal/detail/identity_arrangement.hpp>
64 bool ensure_root_is_returned,
65 bool free_tree_plus_root =
66 ensure_root_is_returned and
67 std::is_same_v<tree_t, lal::graphs::free_tree>
71 std::pair<tree_t, lal::node>,
74from_edge_list_to_tree(std::stringstream& ss)
noexcept
80 uint64_t max_node_idx = 0;
86 while (ss >> curly_bracket) {
87 ss >> u >> v >> curly_bracket;
88 max_node_idx = std::max(max_node_idx, u);
89 max_node_idx = std::max(max_node_idx, v);
100 while (ss >> curly_bracket) {
101 ss >> u >> v >> curly_bracket;
102 t.add_edge_bulk(u,v);
106 if constexpr (std::is_same_v<tree_t, lal::graphs::rooted_tree>) {
113 assert(not t.has_root());
118 if (t.get_in_degree(w) == 0) {
125 assert(t.is_rooted_tree());
134 if constexpr (free_tree_plus_root) {
135 static_assert(std::is_same_v<tree_t, lal::graphs::free_tree>);
158template <
class graph_t>
160(
const std::vector<edge>& edge_list,
bool normalise =
true,
bool check =
true)
163 uint64_t max_vertex_index = 0;
164 for (
const edge& e : edge_list) {
165 max_vertex_index = std::max(max_vertex_index, e.first);
166 max_vertex_index = std::max(max_vertex_index, e.second);
168 const uint64_t num_nodes = 1 + max_vertex_index;
169 graph_t g(num_nodes);
170 g.set_edges(edge_list, normalise, check);
180 bool ensure_root_is_returned,
181 bool free_tree_plus_root =
182 ensure_root_is_returned and
183 std::is_same_v<tree_t, lal::graphs::free_tree>
187 std::pair<tree_t, lal::node>,
190from_head_vector_to_tree(std::stringstream& ss)
noexcept
192 uint64_t num_nodes = 0;
196 while (ss >> u) { ++num_nodes; }
207 uint64_t num_edges_added = 0;
225 t.add_edge_bulk(u - 1, i);
236 assert(r < num_nodes);
238 assert(num_edges_added == num_nodes - 1);
242 if constexpr (std::is_same_v<tree_t, lal::graphs::rooted_tree>) {
245 assert(t.is_rooted_tree());
254 if constexpr (free_tree_plus_root) {
255 static_assert(std::is_same_v<tree_t, lal::graphs::free_tree>);
256 return {std::move(t), r};
270template <detail::linarr_type arr_type>
278 assert(t.is_rooted_tree());
281 const uint64_t n = t.get_num_nodes();
284 const node u = arr[p];
285 if (t.get_root() == u) {
289 const node_t parent = t.get_in_neighbours(u)[0];
290 hv[*p] = arr[parent] + 1;
304template <detail::linarr_type arr_type>
330 bool is_rooted = std::is_base_of_v<graphs::rooted_tree, tree_t>
335 std::pair<graphs::free_tree,node>
337from_head_vector_to_tree(
const head_vector& hv,
bool normalise,
bool check)
340 if (hv.size() == 0) {
341 if constexpr (is_rooted) {
348 if (hv.size() == 1) {
353 if constexpr (is_rooted) {
361 const uint64_t num_nodes = hv.size();
367 node r = num_nodes + 1;
370 uint64_t num_edges_added = 0;
373 for (uint64_t i = 0; i < num_nodes; ++i) {
387 t.add_edge_bulk(hv[i] - 1, i);
397 assert(r < num_nodes);
399 assert(num_edges_added == num_nodes - 1);
402 t.finish_bulk_add(normalise, check);
404 if constexpr (is_rooted) {
407 assert(t.is_rooted_tree());
417 return {std::move(t), r};
450(
const uint64_t *
const L, uint64_t n,
bool normalise =
true,
bool check =
true)
465 uint64_t stack_it = 0;
470 for (
node i = 2; i <= n; ++i) {
473 if (lev[stack_it] + 2 > L[i]) {
474 stack_it = L[i] - 2 + 1;
478 const node r = lev[stack_it];
481 const auto [u,v] = (r == 0 ?
edge(r, i - 1) :
edge(r - 1, i - 1));
487 assert(stack_it == L[i]);
504(
const std::vector<uint64_t>& L, uint64_t n,
bool normalise =
true,
bool check =
true)
523(
const uint64_t *
const seq, uint64_t n,
bool normalise =
true,
bool check =
true)
527 const uint64_t L = n - 2;
529 for (uint64_t i = 0; i < L; ++i) {
530 degree[ seq[i] ] += 1;
540 for (uint64_t v = 0; v < L; ++v) {
541 const auto value = seq[v];
542 bool node_found =
false;
544 while (w < n and not node_found) {
545 if (degree[w] == 1) {
559 for (
node w = 0; w < n; ++w) {
560 if (degree[w] == 1) {
588(
const std::vector<uint64_t>& seq, uint64_t n,
bool normalise =
true,
bool check =
true)
Free tree graph class.
Definition: free_tree.hpp:60
free_tree & add_edge_bulk(node s, node t) noexcept
Adds an edge to the graph.
void finish_bulk_add(bool norm=true, bool check=true) noexcept
Finishes adding edges in bulk.
Rooted tree graph class.
Definition: rooted_tree.hpp:103
graphs::free_tree Prufer_sequence_to_ftree(const uint64_t *const seq, uint64_t n, bool normalise=true, bool check=true) noexcept
Converts the Prüfer sequence of a labelled tree into a tree structure.
Definition: conversions.hpp:523
graph_t from_edge_list_to_graph(const std::vector< edge > &edge_list, bool normalise=true, bool check=true) noexcept
Converts an edge list into a graph.
Definition: conversions.hpp:160
head_vector from_tree_to_head_vector(const graphs::rooted_tree &t, const detail::linarr_wrapper< arr_type > &arr) noexcept
Constructs the head vector representation of a tree.
Definition: conversions.hpp:271
graphs::free_tree level_sequence_to_ftree(const uint64_t *const L, uint64_t n, bool normalise=true, bool check=true) noexcept
Converts the level sequence of a tree into a graph structure.
Definition: conversions.hpp:450
@ num_nodes
Number of nodes of the tree.
Main namespace of the library.
Definition: basic_types.hpp:50
std::vector< uint64_t > head_vector
See Head vector page for further details.
Definition: basic_types.hpp:64
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
Wrapper of a C array for autmatic deallocation of memory.
Definition: data_array.hpp:59
A wrapper to easily use identity arrangements.
Definition: identity_arrangement.hpp:72
Typesafe node type.
Definition: basic_types.hpp:67
Typesafe position type.
Definition: basic_types.hpp:168