13#include "detail/tree_traits.hpp"
14#include "detail/visit.hpp"
16#include <boost/range/adaptor/transformed.hpp>
17#include <boost/range/iterator_range.hpp>
19#include <boost/graph/adjacency_list.hpp>
20#include <boost/graph/graphviz.hpp>
21#include <boost/graph/isomorphism.hpp>
22#include <boost/graph/topological_sort.hpp>
24#include <boost/graph/connected_components.hpp>
25#include <boost/graph/random.hpp>
26#include <boost/graph/random_spanning_tree.hpp>
28#include "detail/adl_resolution.hpp"
29#include "detail/utils.hpp"
34#include <range/v3/all.hpp>
38using no_property = boost::no_property;
91 using edge_parallel_category =
typename base::edge_parallel_category;
119 return boost::degree(u, _graph);
133 return boost::out_degree(v, _graph);
141 auto range = boost::in_edges(u, _graph);
142 return std::distance(range.first, range.second) > 0;
150 auto range = boost::in_edges(u, _graph);
151 assert(std::distance(range.first, range.second) == 1);
152 return source(*range.first);
160 auto range = boost::out_edges(u, _graph);
161 assert(std::distance(range.first, range.second) != 1);
162 return std::distance(range.first, range.second) >= 2;
170 return boost::make_iterator_range(out_edges(u, _graph)) |
171 boost::adaptors::transformed([
this](
auto it) {
return target(it); });
180 auto p = boost::edge(u, v, _graph);
181 return p.second ? std::make_optional(p.first) : std::nullopt;
189 return boost::source(e, _graph);
197 return boost::target(e, _graph);
210 using detail::adl_resolution::in_edges;
226 struct VisWrap : boost::default_dfs_visitor
229 DFSTreeVisitor &_tree_visitor;
230 VisWrap(
k_ary_tree_common &tree, DFSTreeVisitor &v) : _tree(tree), _tree_visitor(v)
235 _tree_visitor(boost::visit::pre, v);
239 _tree_visitor(boost::visit::in, _tree.
target(e));
243 _tree_visitor(boost::visit::post, v);
245 } graph_visitor(*
this, vis);
246 std::vector<boost::default_color_type> colors(boost::num_vertices(_graph));
247 boost::iterator_property_map color_map(colors.begin(), boost::get(boost::vertex_index, _graph));
258 struct VisWrap : boost::default_dfs_visitor
261 DFSTreeVisitor &_tree_visitor;
262 VisWrap(
const k_ary_tree_common &tree, DFSTreeVisitor &v) : _tree(tree), _tree_visitor(v)
267 _tree_visitor(boost::visit::pre, v);
271 _tree_visitor(boost::visit::in, _tree.
target(e));
275 _tree_visitor(boost::visit::post, v);
277 } graph_visitor(*
this, vis);
278 std::vector<boost::default_color_type> colors(boost::num_vertices(_graph));
279 boost::iterator_property_map color_map(colors.begin(), boost::get(boost::vertex_index, _graph));
291 using namespace boost;
292 return boost::write_graphviz(out, *
this, boost::make_label_writer(boost::get(vertex_bundle, *
this)),
293 boost::make_label_writer(boost::get(edge_bundle, *
this)));
302 return base::null_vertex();
306 template <
typename Generator>
307 static auto update_tree(CRTP &tree, std::vector<vertex_descriptor> leaves, Generator &rng)
309 using tree_type = CRTP;
311 if (leaves.size() == 1)
313 return leaves.front();
317 std::uniform_int_distribution<> distrib(1, leaves.size() - 1);
318 int split = distrib(rng);
320 std::vector<vertex_descriptor> left(leaves.begin(), leaves.begin() + split);
321 std::vector<vertex_descriptor> right(leaves.begin() + split, leaves.end());
323 auto parent = boost::add_vertex(tree._graph);
324 if constexpr (std::is_same_v<EdgeProperty, boost::no_property>)
325 tree.add_edges(parent, {update_tree(tree, left, rng), update_tree(tree, right, rng)});
327 tree.add_edges(parent, {std::make_tuple(update_tree(tree, left, rng), EdgeProperty()),
328 std::make_tuple(update_tree(tree, right, rng), EdgeProperty())});
334 template <
typename Generator>
335 static std::tuple<CRTP, vertex_descriptor> make_random_tree(
int n_leaves,
int k_max, Generator &rng)
338 std::vector<vertex_descriptor> leaves(n_leaves);
339 std::transform(leaves.cbegin(), leaves.cend(), leaves.begin(), [&tree](
auto) { return tree.add_vertex(); });
340 vertex_descriptor root = update_tree(tree, leaves, rng);
341 return std::tuple(std::move(tree), root);
348template <
class VertexProperty,
class EdgeProperty>
class k_ary_tree
396 return boost::add_vertex(_graph);
403 assert(children.size() != 0);
406 assert(children.size() > 1);
407 for (
auto const &c : children)
411 std::vector<edge_descriptor> edges(children.size());
412 std::transform(children.cbegin(), children.cend(), edges.begin(),
413 [parent,
this](
auto c) { return boost::add_edge(parent, c, this->_graph).first; });
438template <
class VertexProperty>
439 requires(!std::is_same_v<VertexProperty, no_property>)
441 : public detail::k_ary_tree_common<VertexProperty, no_property,
k_ary_tree<VertexProperty, no_property>>
474 return boost::add_vertex(p, this->_graph);
480 assert(children.size() > 1);
481 for (
auto const &c : children)
486 std::vector<edge_descriptor> edges(children.size());
487 std::transform(children.cbegin(), children.cend(), edges.begin(),
488 [parent,
this](
auto c) { return boost::add_edge(parent, c, this->_graph).first; });
500 return this->_graph[v];
506 return this->_graph[v];
530template <
class EdgeProperty>
531 requires(!std::is_same_v<EdgeProperty, no_property>)
533 : public detail::k_ary_tree_common<no_property, EdgeProperty,
k_ary_tree<no_property, EdgeProperty>>
564 vertex_descriptor add_vertex()
566 return boost::add_vertex(this->_graph);
570 std::vector<edge_descriptor> add_edges(vertex_descriptor parent,
571 const std::vector<std::pair<vertex_descriptor, EdgeProperty>> &children)
573 assert(children.size() > 1);
574 for (
auto const &[c, p] : children)
579 std::vector<edge_descriptor> edges(children.size());
580 std::transform(children.cbegin(), children.cend(), edges.begin(), [parent,
this](
const auto &c) {
581 return boost::add_edge(parent, c.first, c.second, this->_graph).first;
594 return this->_graph[edge];
600 return this->_graph[edge];
626template <
class VertexProperty,
class EdgeProperty>
627 requires(!std::is_same_v<VertexProperty, no_property> && !std::is_same_v<EdgeProperty, no_property>)
629 : public detail::k_ary_tree_common<VertexProperty, EdgeProperty,
k_ary_tree<no_property, EdgeProperty>>
663 return boost::add_vertex(p, this->_graph);
668 std::vector<std::tuple<vertex_descriptor, EdgeProperty>> children)
670 std::cout << children.size() << std::endl;
671 assert(children.size() > 1);
672 for (
auto const &[c, p] : children)
677 std::vector<edge_descriptor> edges(children.size());
678 std::transform(children.cbegin(), children.cend(), edges.begin(), [parent,
this](
const auto &c) {
679 return boost::add_edge(parent, std::get<0>(c), std::get<1>(c), this->_graph).first;
692 return this->_graph[v];
698 return this->_graph[v];
704 return this->_graph[edge];
710 return this->_graph[edge];
718template <
typename Vertex,
typename Edge,
typename Generator>
719auto update_tree(k_ary_tree<Vertex, Edge> &tree,
720 std::vector<
typename k_ary_tree<Vertex, Edge>::vertex_descriptor> leaves, Generator &rng)
722 using tree_type = k_ary_tree<Vertex, Edge>;
723 using vertex_descriptor =
typename tree_type::vertex_descriptor;
725 if (leaves.size() == 1)
727 return leaves.front();
731 std::uniform_int_distribution<> distrib(1, leaves.size() - 1);
732 int split = distrib(rng);
734 std::vector<vertex_descriptor> left(leaves.begin(), leaves.begin() + split);
735 std::vector<vertex_descriptor> right(leaves.begin() + split, leaves.end());
737 vertex_descriptor parent;
739 if constexpr (std::is_same_v<Vertex, boost::no_property>)
740 parent = tree.add_vertex();
742 parent = tree.add_vertex(Vertex());
744 if constexpr (std::is_same_v<Edge, boost::no_property>)
745 tree.add_edges(parent, {update_tree(tree, left, rng), update_tree(tree, right, rng)});
747 tree.add_edges(parent, {{update_tree(tree, left, rng), Edge()}, {update_tree(tree, right, rng), Edge()}});
758template <
typename Vertex = boost::no_property,
typename Edge = boost::no_property,
typename Generator>
759std::pair<quetzal::coalescence::k_ary_tree<Vertex, Edge>,
764 using vertex_descriptor =
typename tree_type::vertex_descriptor;
768 std::vector<vertex_descriptor> leaves(n_leaves);
770 std::transform(leaves.cbegin(), leaves.cend(), leaves.begin(), [&tree](
auto) {
771 if constexpr (std::is_same_v<Vertex, boost::no_property>)
772 return tree.add_vertex();
774 return tree.add_vertex(Vertex());
777 vertex_descriptor root = detail::update_tree(tree, leaves, rng);
778 return std::make_pair(std::move(tree), root);
Definition k_ary_tree.hpp:45
typename base::degree_size_type degree_size_type
Degree size type.
Definition k_ary_tree.hpp:77
typename base::traversal_category traversal_category
The ways in which the vertices in the graph can be traversed.
Definition k_ary_tree.hpp:80
typename base::directed_category directed_category
The graph is bidirected.
Definition k_ary_tree.hpp:83
vertex_descriptor predecessor(vertex_descriptor u) const
The predecessor of vertex .
Definition k_ary_tree.hpp:148
typename base::edge_descriptor edge_descriptor
Edge descriptor.
Definition k_ary_tree.hpp:68
std::optional< edge_descriptor > edge(vertex_descriptor u, vertex_descriptor v) const
Returns the edge between two vertices of the graph if the edge exists.
Definition k_ary_tree.hpp:178
k_ary_tree_common()
Default constructor.
Definition k_ary_tree.hpp:55
degree_size_type degree(vertex_descriptor u) const
Returns the number of in-edges plus out-edges.
Definition k_ary_tree.hpp:117
VertexProperty vertex_property
Vertex information.
Definition k_ary_tree.hpp:71
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 k_ary_tree.hpp:208
typename base::vertex_descriptor vertex_descriptor
Vertex descriptor ("node ID" in other words).
Definition k_ary_tree.hpp:65
typename base::in_edge_iterator in_edge_iterator
Iterate through the in-edges.
Definition k_ary_tree.hpp:86
EdgeProperty edge_property
Edge information.
Definition k_ary_tree.hpp:74
auto successors(vertex_descriptor u) const
The successors of vertex .
Definition k_ary_tree.hpp:168
bool has_successors(vertex_descriptor u) const
Evaluates if vertex has successors.
Definition k_ary_tree.hpp:158
vertex_descriptor target(edge_descriptor e) const
Returns the target vertex of a directed edge.
Definition k_ary_tree.hpp:195
k_ary_tree_common(size_t n)
Constructs a tree with vertices.
Definition k_ary_tree.hpp:60
void to_graphviz(std::ostream &out) const
Print the tree to the graphviz format.
Definition k_ary_tree.hpp:289
tree_traits::model< tree_traits::out_edge_list_type, tree_traits::vertex_list_type, tree_traits::directed_type, VertexProperty, EdgeProperty > base
The type of graph hold by the tree class.
Definition k_ary_tree.hpp:49
void depth_first_search(vertex_descriptor start, DFSTreeVisitor &vis)
Performs a read-and-write depth-first traversal of the vertices starting at vertex .
Definition k_ary_tree.hpp:223
degree_size_type in_degree(vertex_descriptor u) const
Returns the number of in-edges of vertex .
Definition k_ary_tree.hpp:125
degree_size_type out_degree(vertex_descriptor v) const
Returns the number of out-edges of vertex .
Definition k_ary_tree.hpp:131
vertex_descriptor source(edge_descriptor e) const
Returns the source vertex of a directed edge.
Definition k_ary_tree.hpp:187
void depth_first_search(vertex_descriptor start, DFSTreeVisitor &vis) const
Performs a read-only depth-first traversal of the vertices starting at vertex .
Definition k_ary_tree.hpp:255
bool has_predecessor(vertex_descriptor u) const
Evaluates if vertex has a predecessor.
Definition k_ary_tree.hpp:139
static constexpr vertex_descriptor null_vertex()
Null vertex identifier.
Definition k_ary_tree.hpp:300
typename base::out_edge_iterator out_edge_iterator
Iterate through the out-edges.
Definition k_ary_tree.hpp:89
vertex_descriptor find_root_from(vertex_descriptor u) const
Finds the root of the tree graph starting from a vertex .
Definition k_ary_tree.hpp:109
bool is_isomorphic(k_ary_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 k_ary_tree.hpp:100
k_ary_tree()
Default constructor. Initializes a graph with 0 vertices.
Definition k_ary_tree.hpp:646
VertexProperty & operator[](vertex_descriptor v)
Read and write access to the vertex property.
Definition k_ary_tree.hpp:696
const EdgeProperty & operator[](const edge_descriptor &edge) const
Read only access to the edge property.
Definition k_ary_tree.hpp:702
EdgeProperty & operator[](const edge_descriptor &edge)
Read and write access to the edge property.
Definition k_ary_tree.hpp:708
typename base::vertex_descriptor vertex_descriptor
Vertex descriptor.
Definition k_ary_tree.hpp:639
k_ary_tree(size_t n)
Construct graph with vertices.
Definition k_ary_tree.hpp:651
std::vector< edge_descriptor > add_edges(vertex_descriptor parent, std::vector< std::tuple< vertex_descriptor, EdgeProperty > > children)
Add edges from the parent vertex (source) to the children (target)
Definition k_ary_tree.hpp:667
const VertexProperty & operator[](vertex_descriptor v) const
Read only access to the vertex property.
Definition k_ary_tree.hpp:690
vertex_descriptor add_vertex(const VertexProperty &p)
Add a vertex and its properties to the graph.
Definition k_ary_tree.hpp:661
typename base::edge_descriptor edge_descriptor
Edge descriptor.
Definition k_ary_tree.hpp:636
typename base::vertex_descriptor vertex_descriptor
Vertex descriptor.
Definition k_ary_tree.hpp:451
k_ary_tree()
Default constructor. Initializes a graph with 0 vertices.
Definition k_ary_tree.hpp:457
auto add_vertex(const VertexProperty &p)
Add a vertex and its properties to the graph.
Definition k_ary_tree.hpp:472
const VertexProperty & operator[](vertex_descriptor v) const
Read only access to the vertex property.
Definition k_ary_tree.hpp:498
VertexProperty & operator[](vertex_descriptor v)
Read and write access to the vertex property.
Definition k_ary_tree.hpp:504
std::vector< edge_descriptor > add_edges(vertex_descriptor parent, std::vector< vertex_descriptor > children)
Add edges from the parent vertex (source) to the children (target)
Definition k_ary_tree.hpp:478
typename base::edge_descriptor edge_descriptor
Edge descriptor.
Definition k_ary_tree.hpp:448
k_ary_tree(size_t n)
Construct graph with vertices.
Definition k_ary_tree.hpp:462
const EdgeProperty & operator[](const edge_descriptor &edge) const
Read only access to the edge property.
Definition k_ary_tree.hpp:592
typename base::vertex_descriptor vertex_descriptor
Vertex descriptor.
Definition k_ary_tree.hpp:543
typename base::edge_descriptor edge_descriptor
Edge descriptor.
Definition k_ary_tree.hpp:540
k_ary_tree()
Default constructor. Initializses a graph with 0 vertices.
Definition k_ary_tree.hpp:549
EdgeProperty & operator[](const edge_descriptor &edge)
Read and write access to the edge property.
Definition k_ary_tree.hpp:598
k_ary_tree(size_t n)
Construct graph with vertices.
Definition k_ary_tree.hpp:554
vertex_descriptor add_vertex()
Add a vertex to the graph.
Definition k_ary_tree.hpp:394
k_ary_tree(size_t n)
Construct graph with vertices.
Definition k_ary_tree.hpp:385
std::vector< edge_descriptor > add_edges(vertex_descriptor parent, std::vector< vertex_descriptor > children)
Add edges from the parent vertex (source) to the children (target)
Definition k_ary_tree.hpp:400
k_ary_tree()
Default constructor. Initializes a graph with 0 vertices.
Definition k_ary_tree.hpp:380
Definition k_ary_tree.hpp:349
Definition cardinal_k_ary_tree.hpp:46
bool isomorphism(binary_tree< false, Vertex0 > const &g, binary_tree< false, Vertex1 > const &h)
Detects if there is a 1-to-1 mapping of the vertices in one graph to the vertices of another graph su...
Definition cardinal_k_ary_tree.hpp:616
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::k_ary_tree< Vertex, Edge >, typename quetzal::coalescence::k_ary_tree< Vertex, Edge >::vertex_descriptor > get_random_k_ary_tree(int n_leaves, Generator &rng)
Generate a random k-ary tree.
Definition k_ary_tree.hpp:761
boost::vecS vertex_list_type
We don't allow for inserting vertices except at the end and we don't remove vertices....
Definition tree_traits.hpp:31
boost::bidirectionalS directed_type
Coalescent trees are directed acyclic graphs but we need bidirectionality for in-edges access.
Definition tree_traits.hpp:36
boost::setS out_edge_list_type
We want to enforce avoiding multi-graphs (edges with same end nodes)
Definition tree_traits.hpp:27
boost::adjacency_list< Types... > model
Trees are sparse graph in nature, adjacency_matrix would not be justified here.
Definition tree_traits.hpp:24