48#include <lal/graphs/tree_type.hpp>
49#include <lal/graphs/tree.hpp>
50#include <lal/detail/graphs/traversal.hpp>
51#include <lal/detail/data_array.hpp>
52#include <lal/detail/linear_queue.hpp>
53#include <lal/detail/type_traits/conditional_list.hpp>
57namespace maximum_subtrees {
58namespace caterpillar {
97template <
class tree_t>
107 const auto n = t.get_num_nodes();
112 num_vertices_in_path.fill(0);
113 num_vertices_in_path[start_at] = 1;
114 uint64_t max_num_vertices = 0;
116 node farthest = n + 1;
118 bfs.set_process_neighbour(
119 [&](
const auto&,
node u,
node v,
bool) {
120 num_vertices_in_path[v] = num_vertices_in_path[u] + weight[u] + 1;
121 if (max_num_vertices < num_vertices_in_path[v]) {
122 max_num_vertices = num_vertices_in_path[v];
127 bfs.start_at(start_at);
149 std::enable_if_t< std::is_base_of_v<graphs::tree, tree_t>,
bool > =
true
159 std::tuple<uint64_t, std::vector<char>>,
160 std::tuple<uint64_t, std::vector<node>, std::vector<char>>
165 typedef std::vector<node> path;
167 const auto n = t.get_num_nodes();
175 return {0, std::vector<char>(n, 1)};
192 return {0, {0}, {1}};
203 return {0, {0,1}, {1,1}};
211 for (
node u = 0; u < n; ++u) {
212 weight[u] = (t.get_degree(u) == 1 ? 0 : t.get_degree(u) - 2);
234 const auto caterpillar_distance = n - num_vertices_in_path[w_star];
238 return caterpillar_distance;
244 if (caterpillar_distance == 0) {
246 return {caterpillar_distance, std::vector<char>(n,1)};
259 path maximum_caterpillar_backbone;
262 std::vector<char> is_node_in_maximum_caterpillar(n, 0);
265 path path_to_current;
270 path_queue.
push({w_star});
277 [&](
const auto&,
node) {
278 path_to_current = path_queue.
pop();
282 [&](
const auto&,
node u) {
284 maximum_caterpillar_backbone = std::move(path_to_current);
290 [&](
const auto&,
node,
node v,
bool) {
291 auto path_to_v = path_to_current;
292 path_to_v.push_back(v);
293 path_queue.
push(std::move(path_to_v));
300 for (
node u : maximum_caterpillar_backbone) {
301 is_node_in_maximum_caterpillar[u] = 1;
303 for (
node v : t.get_neighbours(u)) {
304 is_node_in_maximum_caterpillar[v] = 1;
308 for (
node v : t.get_in_neighbours(u)) {
309 is_node_in_maximum_caterpillar[v] = 1;
311 for (
node v : t.get_out_neighbours(u)) {
312 is_node_in_maximum_caterpillar[v] = 1;
319 caterpillar_distance,
320 std::move(is_node_in_maximum_caterpillar)
325 caterpillar_distance,
326 std::move(maximum_caterpillar_backbone),
327 std::move(is_node_in_maximum_caterpillar)
Abstract graph Breadth-First Search traversal.
Definition: traversal.hpp:89
void reset() noexcept
Set the graph traversal to its default state.
Definition: traversal.hpp:135
void set_process_current(const BFS_process_one &f) noexcept
Set the function that controls the processing of the current node.
Definition: traversal.hpp:186
void set_terminate(const BFS_bool_one &f) noexcept
Set the function that controls the termination of the loop.
Definition: traversal.hpp:179
void start_at(node source) noexcept
Start traversal at a given node.
Definition: traversal.hpp:152
void set_process_neighbour(const BFS_process_two &f) noexcept
Set the function that controls the processing of the current neighbour.
Definition: traversal.hpp:193
void set_use_rev_edges(bool use) noexcept
Set whether the traversal can use reversed edges.
Definition: traversal.hpp:173
Simple array-like fixed-size queue.
Definition: linear_queue.hpp:69
T && pop() noexcept
Pops the first element of the queue.
Definition: linear_queue.hpp:98
void push(const T &v) noexcept
Insert a new element to the queue.
Definition: linear_queue.hpp:79
void init(std::size_t n) noexcept
Initializes the queue to hold n elements.
Definition: linear_queue.hpp:72
conditional_list_t< bool_sequence< ret_type==result::distance, ret_type==result::distance_vertices, ret_type==result::distance_structure >, type_sequence< uint64_t, std::tuple< uint64_t, std::vector< char > >, std::tuple< uint64_t, std::vector< node >, std::vector< char > > > > max_subtree(const tree_t &t) noexcept
Calculate the maximum spanning caterpillar of a tree.
Definition: tree_maximum_caterpillar.hpp:163
node find_farthest_vertex(const tree_t &t, node start_at, BFS< tree_t > &bfs, data_array< uint64_t > &num_vertices_in_path, data_array< uint64_t > &weight) noexcept
Find the farthest vertex from start_at in the tree.
Definition: tree_maximum_caterpillar.hpp:98
result
What is to be calculated when finding the maximum spanning caterpillar.
Definition: tree_maximum_caterpillar.hpp:61
@ distance_structure
Caterpillar distance plus the caterpillar's structure.
Definition: tree_maximum_caterpillar.hpp:81
@ distance
Only the caterpillar distance.
Definition: tree_maximum_caterpillar.hpp:63
@ distance_vertices
Caterpillar distance plus caterpillar structure's nodes.
Definition: tree_maximum_caterpillar.hpp:70
typename conditional_list< bool_seq, type_seq >::type conditional_list_t
Shorthand for conditional_list.
Definition: conditional_list.hpp:78
@ caterpillar
Caterpillar trees.
Main namespace of the library.
Definition: basic_types.hpp:50
uint64_t node
Node type. See Node / Vertex page for further details.
Definition: basic_types.hpp:53
A sequence of Boolean values.
Definition: bool_sequence.hpp:52
Wrapper of a C array for autmatic deallocation of memory.
Definition: data_array.hpp:59
A sequence of types.
Definition: type_sequence.hpp:51