19#ifndef BOOST_GRAPH_K_ARY_TREE
20#define BOOST_GRAPH_K_ARY_TREE
22#include <boost/config.hpp>
24#include <boost/graph/detail/indexed_properties.hpp>
25#include <boost/graph/graph_mutability_traits.hpp>
26#include <boost/graph/graph_selectors.hpp>
27#include <boost/graph/graph_traits.hpp>
28#include <boost/graph/named_function_params.hpp>
29#include <boost/property_map/property_map.hpp>
31#include <boost/concept/assert.hpp>
32#include <boost/graph/graph_concepts.hpp>
33#include <boost/iterator/iterator_facade.hpp>
34#include <boost/iterator/transform_iterator.hpp>
35#include <boost/range.hpp>
36#include <boost/range/adaptor/reversed.hpp>
41#include "concepts.hpp"
42#include "detail_k_ary_tree.hpp"
47template <
typename Graph>
bool empty(
typename graph_traits<Graph>::vertex_descriptor u, Graph
const &)
49 return u == graph_traits<Graph>::null_vertex();
59template <
bool Predecessor,
typename Vertex = std::
size_t>
class binary_tree;
68template <
typename Vertex>
80 class traversal_category :
public incidence_graph_tag,
public vertex_list_graph_tag
91 using super_t::super_t;
100 BOOST_ASSERT(parent != child);
102 return g.add_left_edge(parent, child);
112 BOOST_ASSERT(parent != child);
114 return g.add_right_edge(parent, child);
130 return g.add_edge(u, v);
147 remove_edge(e.first, e.second, g);
165template <
typename Vertex>
176 class traversal_category :
public bidirectional_graph_tag,
public vertex_list_graph_tag
189 using edge_parallel_category =
typename super_t::edge_parallel_category;
192 using super_t::super_t;
201 BOOST_ASSERT(parent != child);
202 g.nodes[child].predecessor = parent;
203 return g.add_left_edge(parent, child);
213 BOOST_ASSERT(parent != child);
214 g.nodes[child].predecessor = parent;
215 return g.add_right_edge(parent, child);
225 BOOST_ASSERT(!empty(u, g));
227 while (has_predecessor(u, g))
229 u = predecessor(u, g);
232 BOOST_ASSERT(u != graph_traits<binary_tree>::null_vertex());
242 BOOST_ASSERT(!empty(u, g));
244 return left_successor(v, g) == u;
253 BOOST_ASSERT(!empty(u, g));
256 return right_successor(v, g) == u;
265 BOOST_ASSERT(!empty(u, g));
266 BOOST_ASSERT(u < g.nodes.size());
267 return g[u].predecessor != graph_traits<binary_tree>::null_vertex();
276 BOOST_ASSERT(!empty(u, g));
277 BOOST_ASSERT(u < g.nodes.size());
279 return g[u].predecessor;
286 struct make_in_edge_descriptor
288 make_in_edge_descriptor(vertex_descriptor target) : target(target)
292 edge_descriptor operator()(vertex_descriptor source)
const
294 return edge_descriptor(source, target);
297 vertex_descriptor target;
302 using in_edge_iterator = transform_iterator<make_in_edge_descriptor, vertex_descriptor const *, edge_descriptor>;
311 auto const p = has_predecessor(u, g);
312 return std::make_pair(
in_edge_iterator(&g.nodes[u].predecessor, make_in_edge_descriptor(u)),
322 return has_predecessor(u, g);
331 return in_degree(u, g) + out_degree(u, g);
348 if (!g.add_vertex(v) && predecessor(v, g) != g.null_vertex())
352 std::pair<edge_descriptor, bool>
const result = g.add_edge_strict(u, v);
354 g.nodes[v].predecessor = u;
364 BOOST_ASSERT(predecessor(v, g) == u);
366 g.nodes[v].predecessor = super_t::null_vertex();
374 remove_edge(e.first, e.second, g);
382 g.clear_childrens_predecessor(u);
384 g.nodes[u].predecessor = super_t::null_vertex();
394 BOOST_ASSERT(in_degree(u, g) == 0);
405 for (
int i = 0; i != 2; i++)
407 super_t::nodes[super_t::nodes[u].successors[i]].predecessor = super_t::null_vertex();
425template <
typename BinaryTree,
typename Visitor>
426Visitor traverse_nonempty(vertex_descriptor_t<BinaryTree> u, BinaryTree
const &g, Visitor vis)
429 if (has_left_successor(u, g))
430 vis = traverse_nonempty(left_successor(u, g), g, vis);
432 if (has_right_successor(u, g))
433 vis = traverse_nonempty(right_successor(u, g), g, vis);
438template <
typename BinaryTree>
int traverse_step(visit &stage, vertex_descriptor_t<BinaryTree> &u, BinaryTree
const &g)
440 BOOST_CONCEPT_ASSERT((concepts::BidirectionalBinaryTreeConcept<BinaryTree>));
447 if (has_left_successor(u, g))
449 u = left_successor(u, g);
458 if (has_right_successor(u, g))
461 u = right_successor(u, g);
470 if (is_left_successor(u, g))
474 u = predecessor(u, g);
478 throw std::logic_error(
"Unexpected visit stage encountered");
482template <
typename BinaryTree,
typename Visitor>
483Visitor traverse(vertex_descriptor_t<BinaryTree> u, BinaryTree
const &g, Visitor vis)
490 visit stage = visit::pre;
495 traverse_step(stage, u, g);
497 }
while (u != root || stage != visit::post);
502template <
typename BinaryTree0,
typename BinaryTree1>
503bool bifurcate_isomorphic_nonempty(vertex_descriptor_t<BinaryTree0> u, BinaryTree0
const &g,
504 vertex_descriptor_t<BinaryTree1> v, BinaryTree1
const &h)
506 BOOST_CONCEPT_ASSERT((concepts::ForwardBinaryTreeConcept<BinaryTree0>));
507 BOOST_CONCEPT_ASSERT((concepts::ForwardBinaryTreeConcept<BinaryTree1>));
508 BOOST_ASSERT(!empty(u, g));
509 BOOST_ASSERT(!empty(v, h));
511 if (has_left_successor(u, g))
513 if (has_left_successor(v, h))
515 if (!bifurcate_isomorphic_nonempty(left_successor(u, g), g, left_successor(v, h), h))
521 else if (has_left_successor(u, g))
524 if (has_right_successor(u, g))
526 if (has_right_successor(v, h))
528 if (!bifurcate_isomorphic_nonempty(right_successor(u, g), g, right_successor(v, h), h))
534 else if (has_right_successor(u, g))
540template <
typename BinaryTree0,
typename BinaryTree1>
541bool bifurcate_isomorphic(vertex_descriptor_t<BinaryTree0> u, BinaryTree0
const &g, vertex_descriptor_t<BinaryTree1> v,
542 BinaryTree1
const &h)
544 BOOST_CONCEPT_ASSERT((concepts::BidirectionalBinaryTreeConcept<BinaryTree0>));
545 BOOST_CONCEPT_ASSERT((concepts::BidirectionalBinaryTreeConcept<BinaryTree1>));
552 visit visit0 = visit::pre;
553 visit visit1 = visit::pre;
556 traverse_step(visit0, u, g);
557 traverse_step(visit1, v, h);
558 if (visit0 != visit1)
560 if (u == root0 && visit0 == visit::post)
572template <
typename Vertex,
typename DFSTreeVisitor>
577 vis = detail::traverse_nonempty(s, g, vis);
580template <
typename Vertex,
typename DFSTreeVisitor>
581void depth_first_search(binary_tree<false, Vertex>
const &g, vertex_descriptor_t<binary_tree<false, Vertex>> s,
585 vis = detail::traverse_nonempty(s, g, vis);
594template <
typename Vertex,
typename DFSTreeVisitor>
598 vis = detail::traverse(s, g, vis);
601template <
typename Vertex,
typename DFSTreeVisitor>
602void depth_first_search(binary_tree<true, Vertex>
const &g, vertex_descriptor_t<binary_tree<true, Vertex>> s,
605 vis = detail::traverse(s, g, vis);
615template <
typename Vertex0,
typename Vertex1>
618 if (num_vertices(g) != num_vertices(h))
620 return num_vertices(g) == 0 || detail::bifurcate_isomorphic_nonempty(0, g, 0, h);
630template <
typename Vertex0,
typename Vertex1>
633 if (num_vertices(g) != num_vertices(h))
635 return num_vertices(g) == 0 || detail::bifurcate_isomorphic(0, g, 0, h);
Forward Binary Tree.
Definition cardinal_k_ary_tree.hpp:71
directed_tag directed_category
Directed, undirected or bidirectional.
Definition cardinal_k_ary_tree.hpp:77
friend void remove_edge(vertex_descriptor u, vertex_descriptor v, binary_tree &g)
Remove the edge (u,v) from the graph.
Definition cardinal_k_ary_tree.hpp:137
friend void clear_vertex(vertex_descriptor u, binary_tree &g)
Remove all edges to and from vertex u from the graph.
Definition cardinal_k_ary_tree.hpp:153
friend void remove_edge(edge_descriptor e, binary_tree &g)
Remove the edge e from the graph.
Definition cardinal_k_ary_tree.hpp:145
typename super_t::edge_descriptor edge_descriptor
The type for the objects used to identify edges in the graph.
Definition cardinal_k_ary_tree.hpp:85
friend std::pair< edge_descriptor, bool > add_edge(vertex_descriptor u, vertex_descriptor v, binary_tree &g)
Inserts the edge (u,v) into the graph.
Definition cardinal_k_ary_tree.hpp:128
friend edge_descriptor add_left_edge(vertex_descriptor parent, vertex_descriptor child, binary_tree &g)
Add a left edge to the parent vertex.
Definition cardinal_k_ary_tree.hpp:98
typename super_t::vertex_descriptor vertex_descriptor
The type for the objects used to identity vertices in the graph.
Definition cardinal_k_ary_tree.hpp:88
friend edge_descriptor add_right_edge(vertex_descriptor parent, vertex_descriptor child, binary_tree &g)
Add a left edge to the parent vertex.
Definition cardinal_k_ary_tree.hpp:110
Bidirectional Binary Tree.
Definition cardinal_k_ary_tree.hpp:168
friend degree_size_type in_degree(vertex_descriptor u, binary_tree const &g)
Returns the number of in-edges of vertex v in graph g.
Definition cardinal_k_ary_tree.hpp:320
friend vertex_descriptor root(vertex_descriptor u, binary_tree const &g)
Finds the root of the tree graph starting from a vertex u.
Definition cardinal_k_ary_tree.hpp:223
friend bool is_left_successor(vertex_descriptor u, binary_tree const &g)
Evaluate if a vertex is a left successor (child)
Definition cardinal_k_ary_tree.hpp:240
friend bool is_right_successor(vertex_descriptor u, binary_tree const &g)
Evaluate if a vertex is a right successor (child)
Definition cardinal_k_ary_tree.hpp:251
friend bool has_predecessor(vertex_descriptor u, binary_tree const &g)
Evaluates if the vertex has a predecessor (parent)
Definition cardinal_k_ary_tree.hpp:263
friend void remove_edge(vertex_descriptor u, vertex_descriptor v, binary_tree &g)
Remove the edge (u,v) from the graph.
Definition cardinal_k_ary_tree.hpp:362
typename super_t::vertex_descriptor vertex_descriptor
The type for the objects used to identify vertices in the graph.
Definition cardinal_k_ary_tree.hpp:184
friend degree_size_type degree(vertex_descriptor u, binary_tree const &g)
Returns the number of in-edges plus out-edges.
Definition cardinal_k_ary_tree.hpp:329
friend void remove_vertex(vertex_descriptor u, binary_tree &g)
Remove u from the vertex set of the graph.
Definition cardinal_k_ary_tree.hpp:392
friend void clear_vertex(vertex_descriptor u, binary_tree &g)
Remove all edges to and from vertex u from the graph.
Definition cardinal_k_ary_tree.hpp:380
bidirectional_tag directed_category
Directed, undirected or bidirectional.
Definition cardinal_k_ary_tree.hpp:173
friend vertex_descriptor predecessor(vertex_descriptor u, binary_tree const &g)
The predecessor of a given vertex.
Definition cardinal_k_ary_tree.hpp:274
friend void remove_edge(edge_descriptor e, binary_tree &g)
Remove the edge e from the graph.
Definition cardinal_k_ary_tree.hpp:372
transform_iterator< make_in_edge_descriptor, vertex_descriptor const *, edge_descriptor > in_edge_iterator
Iterate through the in-edges.
Definition cardinal_k_ary_tree.hpp:302
typename super_t::edge_descriptor edge_descriptor
The type for the objects used to identify edges in the graph.
Definition cardinal_k_ary_tree.hpp:181
friend std::pair< in_edge_iterator, in_edge_iterator > in_edges(vertex_descriptor u, binary_tree const &g)
Provides iterators to iterate over the in-going edges of vertex u.
Definition cardinal_k_ary_tree.hpp:309
friend std::pair< edge_descriptor, bool > add_edge(vertex_descriptor u, vertex_descriptor v, binary_tree &g)
Inserts the edge (u,v) into the graph.
Definition cardinal_k_ary_tree.hpp:346
typename super_t::degree_size_type degree_size_type
The integer type for vertex degree.
Definition cardinal_k_ary_tree.hpp:187
friend edge_descriptor add_left_edge(vertex_descriptor parent, vertex_descriptor child, binary_tree &g)
Add a left edge to the parent vertex.
Definition cardinal_k_ary_tree.hpp:199
friend edge_descriptor add_right_edge(vertex_descriptor parent, vertex_descriptor child, binary_tree &g)
Add a right edge to the parent vertex.
Definition cardinal_k_ary_tree.hpp:211
void clear_childrens_predecessor(vertex_descriptor u)
Clears the children's predecessor.
Definition cardinal_k_ary_tree.hpp:403
Binary tree base definition for further specialization.
Definition cardinal_k_ary_tree.hpp:59
Definition detail_k_ary_tree.hpp:64
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