LAL: Linear Arrangement Library 23.01.00
A library focused on algorithms on linear arrangements of graphs.
Loading...
Searching...
No Matches
rooted_tree.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 <vector>
49
50// lal includes
51#include <lal/linear_arrangement.hpp>
52#include <lal/graphs/directed_graph.hpp>
53#include <lal/graphs/tree.hpp>
54#include <lal/graphs/free_tree.hpp>
55
56namespace lal {
57namespace graphs {
58
103class rooted_tree : public directed_graph, virtual public tree {
104public:
105 /* CONSTRUCTORS */
106
108 rooted_tree() noexcept : tree(), directed_graph() { }
113 rooted_tree(uint64_t n) noexcept {
115 }
120 rooted_tree(const rooted_tree& r) noexcept : graph(), tree(), directed_graph() {
122 }
123
128 rooted_tree(rooted_tree&& r) noexcept {
129 move_full_rooted_tree(std::forward<rooted_tree>(r));
130 }
131
133 rooted_tree(const free_tree& t, node r) noexcept {
134 init_rooted(t, r);
135 }
137 virtual ~rooted_tree() noexcept { }
138
139 /* OPERATORS */
140
145 rooted_tree& operator= (const rooted_tree& r) noexcept {
147 return *this;
148 }
154 move_full_rooted_tree(std::forward<rooted_tree>(r));
155 return *this;
156 }
157
158 /* MODIFIERS */
159
177 (node u, bool connect = false, bool norm = true, bool check_norm = true) noexcept;
178
201 (node s, node t, bool norm = true, bool check_norm = true) noexcept;
202
216
223 void finish_bulk_add(bool norm = true, bool check = true) noexcept;
224
249 (const std::vector<edge>& edges, bool norm = true, bool check_norm = true)
250 noexcept;
251
285 (const std::vector<edge>& edges, bool norm = true, bool check_norm = true)
286 noexcept;
287
305 (node s, node t, bool norm = false, bool check_norm = true) noexcept;
306
328 (const std::vector<edge>& edges, bool norm = true, bool check_norm = true)
329 noexcept;
330
351 (node u, bool norm = true, bool check_norm = true)
352 noexcept;
353
378 void disjoint_union(const rooted_tree& t, bool connect_roots = true)
379 noexcept;
380
395 void init_rooted(const free_tree& t, node r) noexcept;
396
403 void calculate_size_subtrees() noexcept;
404
405 void calculate_tree_type() noexcept;
406
407 /* SETTERS */
408
419 void set_root(node r) noexcept {
420 // if the tree is empty simply consider it has a root...
421 // although it really doesn't
422
423 if (get_num_nodes() > 0) {
424#if defined DEBUG
425 assert(has_node(r));
426 assert(is_root_valid(r));
427#endif
428 m_root = r;
429 }
430 m_has_root = true;
432 m_is_tree_type_valid = false;
433 }
434
435 /* GETTERS */
436
445 bool is_root_valid(node r) const noexcept {
446#if defined DEBUG
447 assert(has_node(r));
448#endif
449 return get_in_degree(r) == 0;
450 }
451
452 bool can_add_edge(node s, node t) const noexcept;
453
454 bool can_add_edges(const std::vector<edge>& edges) const noexcept;
455
456 bool is_rooted() const noexcept { return true; }
457
468 bool is_rooted_tree() const noexcept { return is_tree() and has_root(); }
469
471 node get_root() const noexcept {
472#if defined DEBUG
473 assert(has_root());
474#endif
475 return m_root;
476 }
479 bool has_root() const noexcept { return m_has_root; }
480
487 uint64_t get_num_nodes_subtree(node u) const noexcept {
488#if defined DEBUG
489 assert(has_node(u));
490 assert(are_size_subtrees_valid());
491#endif
492 return m_size_subtrees[u];
493 }
494
505 bool are_size_subtrees_valid() const noexcept
506 { return m_are_size_subtrees_valid; }
507
538 std::vector<edge> get_edges_subtree(node u, bool relab = false) const noexcept;
539
547 rooted_tree get_subtree(node u) const noexcept;
548
555 (bool norm = true, bool check = true) const noexcept;
556
566 head_vector get_head_vector(const linear_arrangement& arr = {}) const noexcept;
567
578 bool subtree_contains_node(node r, node u) const noexcept;
579
580protected:
584 bool m_has_root = false;
585
592 std::vector<uint64_t> m_size_subtrees;
595
596protected:
599 virtual void _init(uint64_t n) noexcept {
602 m_size_subtrees = std::vector<uint64_t>(n);
603 if (n <= 1) {
604 set_root(0);
605 }
606 }
609 virtual void _clear() noexcept {
612 m_size_subtrees.clear();
613 }
614
616 node u, node v,
617 uint64_t * const root_of,
618 uint64_t * const root_size
619 ) noexcept;
621 node u, node v,
622 uint64_t * const root_of,
623 uint64_t * const root_size
624 ) const noexcept;
625
627 node u, node v,
628 uint64_t * const root_of,
629 uint64_t * const root_size
630 ) noexcept;
632 node u, node v,
633 uint64_t * const root_of,
634 uint64_t * const root_size
635 ) const noexcept;
636
638 node u,
639 uint64_t * const root_of, uint64_t * const root_size
640 ) noexcept;
642 node u,
643 uint64_t * const root_of, uint64_t * const root_size
644 ) const noexcept;
645
647 void copy_full_rooted_tree(const rooted_tree& r) noexcept {
648 // copy directed_graph class
650
651 // copy only tree's members
653
654 // copy this class' members
655 m_root = r.m_root;
656 m_has_root = r.m_has_root;
657 m_size_subtrees = r.m_size_subtrees;
658 m_are_size_subtrees_valid = r.m_are_size_subtrees_valid;
659 }
662 // move-assign directed_graph class
663 move_full_directed_graph(std::forward<rooted_tree>(r));
664
665 // move-assign only tree's members
666 tree_only_move(std::forward<rooted_tree>(r));
667
668 // move this class' members
669 m_root = r.m_root;
670 m_has_root = r.m_has_root;
671 m_size_subtrees = std::move(r.m_size_subtrees);
672 m_are_size_subtrees_valid = r.m_are_size_subtrees_valid;
673
674 r.m_root = 0;
675 r.m_has_root = false;
676 r.m_are_size_subtrees_valid = false;
677 }
678
679private:
682};
683
684} // -- namespace graphs
685} // -- namespace lal
Directed graph class.
Definition: directed_graph.hpp:68
void move_full_directed_graph(directed_graph &&d) noexcept
Moves all members of this class and the parent class.
Definition: directed_graph.hpp:416
directed_graph() noexcept
Empty constructor.
Definition: directed_graph.hpp:73
void copy_full_directed_graph(const directed_graph &d) noexcept
Copies all members of this class and the parent class.
Definition: directed_graph.hpp:408
virtual void _init(uint64_t n) noexcept
Initialises memory of directed_graph and graph classes.
Definition: directed_graph.hpp:397
void disjoint_union(const directed_graph &g) noexcept
Disjoint union of graphs.
virtual directed_graph & remove_node(node u, bool norm=true, bool check_norm=true) noexcept
Remove a node from this graph.
virtual void _clear() noexcept
Clears the memory of directed_graph and graph classes.
Definition: directed_graph.hpp:402
uint64_t get_in_degree(node u) const noexcept
Returns the in-degree of a node.
Definition: directed_graph.hpp:365
Free tree graph class.
Definition: free_tree.hpp:60
Abstract class for graphs.
Definition: graph.hpp:69
bool has_node(node u) const noexcept
Returns true if node u is in this graph.
Definition: graph.hpp:192
uint64_t get_num_nodes() const noexcept
Returns the number of ndoes.
Definition: graph.hpp:198
Rooted tree graph class.
Definition: rooted_tree.hpp:103
rooted_tree(rooted_tree &&r) noexcept
Move constructor.
Definition: rooted_tree.hpp:128
virtual rooted_tree & remove_edges_incident_to(node u, bool norm=true, bool check_norm=true) noexcept
Remove all edges incident to a given vertex.
bool m_has_root
Has the root been set?
Definition: rooted_tree.hpp:584
void copy_full_rooted_tree(const rooted_tree &r) noexcept
Copies all members of this class and the parent class.
Definition: rooted_tree.hpp:647
rooted_tree & add_edge_bulk(node s, node t) noexcept
Adds an edge to the graph.
void disjoint_union(const rooted_tree &t, bool connect_roots=true) noexcept
Disjoint union of trees.
void update_union_find_after_edge_add(node u, node v, uint64_t *const root_of, uint64_t *const root_size) noexcept
Update the union find data structure after an edge addition.
head_vector get_head_vector(const linear_arrangement &arr={}) const noexcept
Converts a rooted tree into a head vector.
node m_root
Root of the tree.
Definition: rooted_tree.hpp:582
rooted_tree & operator=(const rooted_tree &r) noexcept
Copy assignment operator.
Definition: rooted_tree.hpp:145
rooted_tree get_subtree(node u) const noexcept
Retrieve the subtree rooted at node u.
rooted_tree & add_edge(node s, node t, bool norm=true, bool check_norm=true) noexcept
Adds an edge to the tree.
rooted_tree & remove_node(node u, bool connect=false, bool norm=true, bool check_norm=true) noexcept
Remove a node from this tree.
virtual void _init(uint64_t n) noexcept
Definition: rooted_tree.hpp:599
virtual ~rooted_tree() noexcept
Destructor.
Definition: rooted_tree.hpp:137
void calculate_size_subtrees() noexcept
Calculates the number of nodes at every rooted subtree.
void update_union_find_after_edge_remove(node u, node v, uint64_t *const root_of, uint64_t *const root_size) const noexcept
Update the union find data structure after an edge removal.
void set_root(node r) noexcept
Set the root of this tree.
Definition: rooted_tree.hpp:419
void init_rooted(const free_tree &t, node r) noexcept
Initialiser with tree and root node.
rooted_tree(uint64_t n) noexcept
Constructor with number of nodes and root node.
Definition: rooted_tree.hpp:113
rooted_tree & set_edges(const std::vector< edge > &edges, bool norm=true, bool check_norm=true) noexcept
Sets the edges to the graph.
bool can_add_edge(node s, node t) const noexcept
Can this edge be added?
rooted_tree & remove_edge(node s, node t, bool norm=false, bool check_norm=true) noexcept
Remove an edge from this graph.
rooted_tree & add_edges(const std::vector< edge > &edges, bool norm=true, bool check_norm=true) noexcept
Adds a list of edges to the graph.
void update_union_find_after_edge_add(node u, node v, uint64_t *const root_of, uint64_t *const root_size) const noexcept
Update the union find data structure after an edge addition.
bool is_root_valid(node r) const noexcept
Is the root valid?
Definition: rooted_tree.hpp:445
void update_union_find_before_incident_edges_removed(node u, uint64_t *const root_of, uint64_t *const root_size) const noexcept
Update the union find data structure before the removal of all edges incident to a node.
std::vector< edge > get_edges_subtree(node u, bool relab=false) const noexcept
Retrieve the edges of the subtree rooted at u.
std::vector< uint64_t > m_size_subtrees
Number of nodes of the subtrees rooted at a certain node.
Definition: rooted_tree.hpp:592
rooted_tree & remove_edges(const std::vector< edge > &edges, bool norm=true, bool check_norm=true) noexcept
Remove an edge from this graph.
bool has_root() const noexcept
Definition: rooted_tree.hpp:479
node get_root() const noexcept
Return the root of this tree.
Definition: rooted_tree.hpp:471
bool is_rooted() const noexcept
Returns whether this tree is a rooted tree.
Definition: rooted_tree.hpp:456
rooted_tree(const rooted_tree &r) noexcept
Copy constructor.
Definition: rooted_tree.hpp:120
bool subtree_contains_node(node r, node u) const noexcept
Does the subtree rooted at r contain node u?
void calculate_tree_type() noexcept
Calculates the type of tree.
rooted_tree() noexcept
Empty constructor.
Definition: rooted_tree.hpp:108
void finish_bulk_add(bool norm=true, bool check=true) noexcept
Finishes adding edges in bulk.
void update_union_find_after_edge_remove(node u, node v, uint64_t *const root_of, uint64_t *const root_size) noexcept
Update the union find data structure after an edge removal.
bool can_add_edges(const std::vector< edge > &edges) const noexcept
Can these edges be added?
void update_union_find_before_incident_edges_removed(node u, uint64_t *const root_of, uint64_t *const root_size) noexcept
Update the union find data structure before the removal of all edges incident to a node.
uint64_t get_num_nodes_subtree(node u) const noexcept
Get the size of a subtree rooted at a given node.
Definition: rooted_tree.hpp:487
virtual void _clear() noexcept
Definition: rooted_tree.hpp:609
void move_full_rooted_tree(rooted_tree &&r) noexcept
Moves all members of this class and the parent class.
Definition: rooted_tree.hpp:661
bool are_size_subtrees_valid() const noexcept
Is a recalculation of the subtree's sizes needed?
Definition: rooted_tree.hpp:505
free_tree to_free_tree(bool norm=true, bool check=true) const noexcept
Converts this rooted tree into a free tree (see free_tree).
rooted_tree(const free_tree &t, node r) noexcept
Constructor with tree and root node.
Definition: rooted_tree.hpp:133
bool is_rooted_tree() const noexcept
Is this tree a valid rooted tree?
Definition: rooted_tree.hpp:468
bool m_are_size_subtrees_valid
Are the contents of m_size_subtrees valid?
Definition: rooted_tree.hpp:594
Tree graph class.
Definition: tree.hpp:73
bool is_tree() const noexcept
Is this graph is an actual tree?
Definition: tree.hpp:143
tree() noexcept
Empty constructor.
Definition: tree.hpp:78
void tree_only_copy(const tree &t) noexcept
Copies only members of class tree.
Definition: tree.hpp:327
void tree_only_move(tree &&t) noexcept
Moves only members of class tree.
Definition: tree.hpp:335
void tree_only_init(uint64_t n) noexcept
Initialises only the memory of class tree.
Definition: tree.hpp:306
bool m_is_tree_type_valid
Is the type of this tree valid?
Definition: tree.hpp:299
void tree_only_clear() noexcept
Clears the memory used by only class tree.
Definition: tree.hpp:318
Linear arrangement of vertices.
Definition: linear_arrangement.hpp:103
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