15#include <boost/range/iterator_range.hpp>
16#include <range/v3/all.hpp>
19#include <boost/graph/graphviz.hpp>
21#include "detail/adl_resolution.hpp"
22#include "detail/cardinal_k_ary_tree.hpp"
23#include "detail/tree_traits.hpp"
24#include "detail/utils.hpp"
34using no_property = boost::no_property;
40template <
typename T>
struct tag
48 template <
typename T>
operator T() &&
50 return std::forward<F>(f)(
tag<T>{});
56template <
typename... Args>
auto initpack(Args &&...args)
59 using Ret =
typename decltype(t)::type;
60 return Ret{std::forward<Args>(args)...};
64template <
typename VertexDescriptor,
typename VertexProperty>
struct VertexManager
66 using vertex_descriptor = VertexDescriptor;
67 using vertex_hashmap_type = std::map<vertex_descriptor, VertexProperty>;
69 vertex_hashmap_type _property_map;
71 template <
typename... Args>
void add_vertex_to_manager(vertex_descriptor v, Args &&...args)
73 _property_map[v] = {std::forward<Args>(args)...};
76 const VertexProperty &operator[](vertex_descriptor v)
const
78 return _property_map.at(v);
81 VertexProperty &operator[](vertex_descriptor v)
83 return _property_map[v];
87template <
typename EdgeDescriptor,
typename EdgeProperty>
struct EdgeManager
89 using edge_descriptor = EdgeDescriptor;
90 using vertex_descriptor =
typename EdgeDescriptor::first_type;
91 using edge_hashmap_type = std::map<edge_descriptor, EdgeProperty>;
93 edge_hashmap_type _property_map;
95 void add_edges(EdgeDescriptor u,
const EdgeProperty &left, EdgeDescriptor v,
const EdgeProperty &right)
97 _property_map.insert({u, left});
98 _property_map.insert({v, right});
101 template <
typename... Args>
102 void add_edges(EdgeDescriptor u, std::tuple<Args...> left, EdgeDescriptor v, std::tuple<Args...> right)
104 _property_map.emplace(
105 std::piecewise_construct, std::forward_as_tuple(u),
106 std::forward_as_tuple(std::apply([](
auto &&...args) {
return initpack(args...); }, left)));
107 _property_map.emplace(
108 std::piecewise_construct, std::forward_as_tuple(v),
109 std::forward_as_tuple(std::apply([](
auto &&...args) {
return initpack(args...); }, right)));
112 template <
typename VertexDescriptor>
113 const EdgeProperty &operator[](
const std::pair<VertexDescriptor, VertexDescriptor> &edge)
const
115 return _property_map.at(edge);
118 template <
typename VertexDescriptor>
119 EdgeProperty &operator[](
const std::pair<VertexDescriptor, VertexDescriptor> &edge)
121 return _property_map.at(edge);
161 using edge_parallel_category =
typename base::edge_parallel_category;
172 using detail::adl_resolution::isomorphism;
173 return isomorphism(_graph, other._graph);
182 using detail::adl_resolution::root;
183 return root(u, _graph);
191 using detail::adl_resolution::degree;
206 using detail::adl_resolution::out_degree;
215 using detail::adl_resolution::has_predecessor;
224 using detail::adl_resolution::predecessor;
241 return boost::make_iterator_range(out_edges(u, _graph)) |
242 boost::adaptors::transformed([
this](
auto it) {
return target(it, _graph); });
250 using detail::adl_resolution::is_left_successor;
259 using detail::adl_resolution::is_right_successor;
273 using detail::adl_resolution::in_edges;
314 using namespace boost;
315 return boost::write_graphviz(out, *
this, boost::make_label_writer(boost::get(vertex_bundle, *
this)),
316 boost::make_label_writer(boost::get(edge_bundle, *
this)));
323 return base::null_vertex();
329template <
class VertexProperty,
class EdgeProperty>
class binary_tree
376 using boost::add_vertex;
377 return add_vertex(_graph);
384 assert(parent != left);
385 assert(parent != right);
386 assert(left != right);
387 return std::make_pair(add_left_edge(parent, left, _graph), add_right_edge(parent, right, _graph));
412template <
class VertexProperty>
413 requires(!std::is_same_v<VertexProperty, no_property>)
449 using boost::add_vertex;
451 _vertex_manager.add_vertex_to_manager(v, p);
459 assert(parent != left);
460 assert(parent != right);
461 assert(left != right);
462 return {add_left_edge(parent, left, this->_graph), add_right_edge(parent, right, this->_graph)};
473 return _vertex_manager[v];
479 return _vertex_manager[v];
500template <
class EdgeProperty>
501 requires(!std::is_same_v<EdgeProperty, no_property>)
534 vertex_descriptor add_vertex()
537 using boost::add_vertex;
538 return add_vertex(this->_graph);
542 std::pair<edge_descriptor, edge_descriptor> add_edges(vertex_descriptor parent,
543 const std::pair<vertex_descriptor, EdgeProperty> &left,
544 const std::pair<vertex_descriptor, EdgeProperty> &right)
546 assert(parent != left.first);
547 assert(parent != right.first);
548 assert(left.first != right.first);
550 auto left_edge = add_left_edge(parent, left.first, this->_graph);
551 auto right_edge = add_right_edge(parent, right.first, this->_graph);
553 _edge_manager.add_edges(left_edge, left.second, right_edge, right.second);
554 return {left_edge, right_edge};
565 return _edge_manager[edge];
571 return _edge_manager[edge];
597template <
class VertexProperty,
class EdgeProperty>
598 requires(!std::is_same_v<VertexProperty, no_property> && !std::is_same_v<EdgeProperty, no_property>)
635 using boost::add_vertex;
637 _vertex_manager.add_vertex_to_manager(v, p);
643 const std::pair<vertex_descriptor, EdgeProperty> &left,
644 const std::pair<vertex_descriptor, EdgeProperty> &right)
646 assert(parent != left.first);
647 assert(parent != right.first);
648 assert(left.first != right.first);
650 auto left_edge = add_left_edge(parent, left.first, this->_graph);
651 auto right_edge = add_right_edge(parent, right.first, this->_graph);
653 _edge_manager.add_edges(left_edge, left.second, right_edge, right.second);
654 return {left_edge, right_edge};
665 return _vertex_manager[v];
671 return _vertex_manager[v];
677 return _edge_manager[edge];
683 return _edge_manager[edge];
691template <
typename Vertex,
typename Edge,
typename Generator>
696 using vertex_descriptor =
typename tree_type::vertex_descriptor;
698 if (leaves.size() == 1)
700 return leaves.front();
704 std::uniform_int_distribution<> distrib(1, leaves.size() - 1);
705 int split = distrib(rng);
707 std::vector<vertex_descriptor> left(leaves.begin(), leaves.begin() + split);
708 std::vector<vertex_descriptor> right(leaves.begin() + split, leaves.end());
710 vertex_descriptor parent;
712 if constexpr (std::is_same_v<Vertex, boost::no_property>)
713 parent = tree.add_vertex();
715 parent = tree.add_vertex(Vertex());
717 if constexpr (std::is_same_v<Edge, boost::no_property>)
718 tree.add_edges(parent, update_tree(tree, left, rng), update_tree(tree, right, rng));
720 tree.add_edges(parent, {update_tree(tree, left, rng), Edge()}, {update_tree(tree, right, rng), Edge()});
731template <
typename Vertex = boost::no_property,
typename Edge = boost::no_property,
typename Generator>
732std::pair<quetzal::coalescence::binary_tree<Vertex, Edge>,
737 using vertex_descriptor =
typename tree_type::vertex_descriptor;
741 std::vector<vertex_descriptor> leaves(n_leaves);
743 std::transform(leaves.cbegin(), leaves.cend(), leaves.begin(), [&tree](
auto) {
744 if constexpr (std::is_same_v<Vertex, boost::no_property>)
745 return tree.add_vertex();
747 return tree.add_vertex(Vertex());
750 vertex_descriptor root = detail::update_tree(tree, leaves, rng);
751 return std::make_pair(std::move(tree), root);
VertexProperty & operator[](vertex_descriptor v)
Read and write access to the vertex property.
Definition binary_tree.hpp:669
std::pair< edge_descriptor, edge_descriptor > add_edges(vertex_descriptor parent, const std::pair< vertex_descriptor, EdgeProperty > &left, const std::pair< vertex_descriptor, EdgeProperty > &right)
Add edges between the parent vertex and the two children.
Definition binary_tree.hpp:642
const VertexProperty & operator[](vertex_descriptor v) const
Read only access to the vertex property.
Definition binary_tree.hpp:663
binary_tree()
Default constructor. Initializes a graph with 0 vertices.
Definition binary_tree.hpp:617
EdgeProperty & operator[](const edge_descriptor &edge)
Read and write access to the edge property.
Definition binary_tree.hpp:681
const EdgeProperty & operator[](const edge_descriptor &edge) const
Read only access to the edge property.
Definition binary_tree.hpp:675
typename base::vertex_descriptor vertex_descriptor
Vertex descriptor.
Definition binary_tree.hpp:611
vertex_descriptor add_vertex(const VertexProperty &p)
Add a vertex and its properties to the graph.
Definition binary_tree.hpp:632
typename base::edge_descriptor edge_descriptor
Edge descriptor.
Definition binary_tree.hpp:608
binary_tree(size_t n)
Construct graph with vertices.
Definition binary_tree.hpp:622
vertex_descriptor add_vertex(const VertexProperty &p)
Add a vertex and its properties to the graph.
Definition binary_tree.hpp:446
binary_tree()
Default constructor. Initializes a graph with 0 vertices.
Definition binary_tree.hpp:431
typename base::vertex_descriptor vertex_descriptor
Vertex descriptor.
Definition binary_tree.hpp:425
binary_tree(size_t n)
Construct graph with vertices.
Definition binary_tree.hpp:436
std::pair< edge_descriptor, edge_descriptor > add_edges(vertex_descriptor parent, vertex_descriptor left, vertex_descriptor right)
Add edges between the parent vertex and the two children.
Definition binary_tree.hpp:456
typename base::edge_descriptor edge_descriptor
Edge descriptor.
Definition binary_tree.hpp:422
const VertexProperty & operator[](vertex_descriptor v) const
Read only access to the vertex property.
Definition binary_tree.hpp:471
VertexProperty & operator[](vertex_descriptor v)
Read and write access to the vertex property.
Definition binary_tree.hpp:477
const EdgeProperty & operator[](const edge_descriptor &edge) const
Read only access to the edge property.
Definition binary_tree.hpp:563
binary_tree(size_t n)
Construct graph with vertices.
Definition binary_tree.hpp:524
typename base::vertex_descriptor vertex_descriptor
Vertex descriptor.
Definition binary_tree.hpp:513
binary_tree()
Default constructor. Initializses a graph with 0 vertices.
Definition binary_tree.hpp:519
typename base::edge_descriptor edge_descriptor
Edge descriptor.
Definition binary_tree.hpp:510
EdgeProperty & operator[](const edge_descriptor &edge)
Read and write access to the edge property.
Definition binary_tree.hpp:569
vertex_descriptor add_vertex()
Add a vertex to the graph.
Definition binary_tree.hpp:373
std::pair< edge_descriptor, edge_descriptor > add_edges(vertex_descriptor parent, vertex_descriptor left, vertex_descriptor right)
Add edges between the parent vertex and the two children.
Definition binary_tree.hpp:381
binary_tree(size_t n)
Construct graph with vertices.
Definition binary_tree.hpp:364
binary_tree()
Default constructor. Initializes a graph with 0 vertices.
Definition binary_tree.hpp:359
Definition binary_tree.hpp:330
Definition binary_tree.hpp:126
typename base::vertex_descriptor vertex_descriptor
Vertex descriptor ("node ID" in other words).
Definition binary_tree.hpp:144
typename base::edge_descriptor edge_descriptor
Edge descriptor.
Definition binary_tree.hpp:147
bool has_predecessor(vertex_descriptor u) const
Evaluates if vertex has a predecessor.
Definition binary_tree.hpp:213
auto successors(vertex_descriptor u) const
The successors of vertex .
Definition binary_tree.hpp:239
bool is_right_successor(vertex_descriptor u) const
Evaluate if vertex is a right successor.
Definition binary_tree.hpp:257
binary_tree_common(size_t n)
Constructs a tree with vertices.
Definition binary_tree.hpp:139
bool is_left_successor(vertex_descriptor u) const
Evaluate if vertex is a left successor.
Definition binary_tree.hpp:248
vertex_descriptor predecessor(vertex_descriptor u) const
The predecessor of vertex .
Definition binary_tree.hpp:222
bool is_isomorphic(binary_tree_common const &other) const
Detects if there is a 1-to-1 mapping of the vertices in one graph to the vertices of another graph su...
Definition binary_tree.hpp:170
typename base::in_edge_iterator in_edge_iterator
Iterate through the in-edges.
Definition binary_tree.hpp:159
typename base::directed_category directed_category
The graph is bidirected.
Definition binary_tree.hpp:156
typename base::degree_size_type degree_size_type
Degree size type.
Definition binary_tree.hpp:150
void depth_first_search(vertex_descriptor s, DFSTreeVisitor &vis) const
Performs a read-only depth-first traversal of the vertices starting at vertex .
Definition binary_tree.hpp:298
void to_graphviz(std::ostream &out) const
Print the tree to the graphviz format.
Definition binary_tree.hpp:312
void depth_first_search(vertex_descriptor s, DFSTreeVisitor &vis)
Performs a read-and-write depth-first traversal of the vertices starting at vertex .
Definition binary_tree.hpp:286
degree_size_type in_degree(vertex_descriptor u) const
Returns the number of in-edges of vertex .
Definition binary_tree.hpp:198
bool has_successors(vertex_descriptor u) const
Evaluates if vertex has successors.
Definition binary_tree.hpp:231
degree_size_type degree(vertex_descriptor u) const
Returns the number of in-edges plus out-edges.
Definition binary_tree.hpp:189
binary_tree_common()
Default constructor.
Definition binary_tree.hpp:134
vertex_descriptor find_root_from(vertex_descriptor u) const
Finds the root of the tree graph starting from a vertex .
Definition binary_tree.hpp:180
typename base::traversal_category traversal_category
The ways in which the vertices in the graph can be traversed.
Definition binary_tree.hpp:153
std::pair< in_edge_iterator, in_edge_iterator > in_edges(vertex_descriptor u) const
Provides iterators to iterate over the in-going edges of vertex .
Definition binary_tree.hpp:271
degree_size_type out_degree(vertex_descriptor v) const
Returns the number of out-edges of vertex .
Definition binary_tree.hpp:204
Definition cardinal_k_ary_tree.hpp:46
void depth_first_search(binary_tree< false, Vertex > &g, vertex_descriptor_t< binary_tree< false, Vertex > > s, DFSTreeVisitor &vis)
performs a depth-first traversal of the vertices in a directed graph
Definition cardinal_k_ary_tree.hpp:573
Simulation of coalescent trees.
Definition coalescence.hpp:26
std::pair< quetzal::coalescence::binary_tree< Vertex, Edge >, typename quetzal::coalescence::binary_tree< Vertex, Edge >::vertex_descriptor > get_random_binary_tree(int n_leaves, Generator &rng)
Generate a random binary tree.
Definition binary_tree.hpp:734
Definition binary_tree.hpp:88
Definition binary_tree.hpp:65
Definition binary_tree.hpp:46
Definition binary_tree.hpp:41