11#include <boost/graph/breadth_first_search.hpp>
12#include <boost/graph/depth_first_search.hpp>
26enum class traversal_order {
31template <
typename GraphWrapper, traversal_order Order>
34 using NodeID =
typename GraphWrapper::NodeType;
35 using value_type = std::pair<NodeID, NodeID>;
37 traversal_edges_view(
const GraphWrapper& graph,
const NodeID& start) : graph(&graph), start(start) {}
41 using iterator_category = std::input_iterator_tag;
42 using value_type = traversal_edges_view::value_type;
43 using difference_type = std::ptrdiff_t;
44 using reference =
const value_type&;
48 iterator(
const GraphWrapper& graph,
const NodeID& start)
49 : state(std::make_shared<traversal_state>(graph, start)) {
53 reference operator*()
const {
54 return *state->current;
57 const value_type* operator->()
const {
58 return &*state->current;
66 void operator++(
int) {
70 friend bool operator==(
const iterator& it, std::default_sentinel_t) {
71 return !it.state || it.state->done;
74 friend bool operator==(std::default_sentinel_t sentinel,
const iterator& it) {
75 return it == sentinel;
79 using GraphType =
typename GraphWrapper::GraphType;
80 using VertexDesc =
typename GraphWrapper::VertexDesc;
81 using OutEdgeIterator =
typename boost::graph_traits<GraphType>::out_edge_iterator;
85 OutEdgeIterator current;
89 struct traversal_state {
90 traversal_state(
const GraphWrapper& graph,
const NodeID& start)
92 colors(boost::num_vertices(graph.get_impl()), boost::white_color),
93 current(std::nullopt),
95 const auto start_vertex = graph.get_id_to_bgl_map().at(start);
96 colors[graph.get_vertex_index(start_vertex)] = boost::gray_color;
97 if constexpr (Order == traversal_order::bfs) {
98 bfs_queue.push(start_vertex);
100 push_dfs_vertex(start_vertex);
104 void push_dfs_vertex(VertexDesc vertex) {
105 auto [edge_it, edge_end] = boost::out_edges(vertex, graph->get_impl());
106 dfs_stack.push_back(edge_cursor{vertex, edge_it, edge_end});
109 const GraphWrapper* graph;
110 std::vector<boost::default_color_type> colors;
111 std::queue<VertexDesc> bfs_queue;
112 std::optional<edge_cursor> bfs_cursor;
113 std::vector<edge_cursor> dfs_stack;
114 std::optional<value_type> current;
119 if (!state || state->done) {
123 state->current.reset();
124 if constexpr (Order == traversal_order::bfs) {
132 while (!state->bfs_queue.empty()) {
133 if (!state->bfs_cursor.has_value()) {
134 const auto vertex = state->bfs_queue.front();
135 auto [edge_it, edge_end] = boost::out_edges(vertex, state->graph->get_impl());
136 state->bfs_cursor = edge_cursor{vertex, edge_it, edge_end};
139 while (state->bfs_cursor->current != state->bfs_cursor->end) {
140 const auto edge = *state->bfs_cursor->current;
141 ++state->bfs_cursor->current;
142 const auto child = boost::target(edge, state->graph->get_impl());
143 const auto child_index = state->graph->get_vertex_index(child);
144 if (state->colors[child_index] == boost::white_color) {
145 state->colors[child_index] = boost::gray_color;
146 state->bfs_queue.push(child);
147 state->current = value_type{
148 state->graph->get_node_id(state->bfs_cursor->vertex),
149 state->graph->get_node_id(child)
155 state->colors[state->graph->get_vertex_index(state->bfs_cursor->vertex)] = boost::black_color;
156 state->bfs_queue.pop();
157 state->bfs_cursor.reset();
164 while (!state->dfs_stack.empty()) {
165 auto& cursor = state->dfs_stack.back();
166 while (cursor.current != cursor.end) {
167 const auto edge = *cursor.current;
169 const auto child = boost::target(edge, state->graph->get_impl());
170 const auto child_index = state->graph->get_vertex_index(child);
171 if (state->colors[child_index] == boost::white_color) {
172 state->colors[child_index] = boost::gray_color;
173 state->current = value_type{
174 state->graph->get_node_id(cursor.vertex),
175 state->graph->get_node_id(child)
177 state->push_dfs_vertex(child);
182 state->colors[state->graph->get_vertex_index(cursor.vertex)] = boost::black_color;
183 state->dfs_stack.pop_back();
189 std::shared_ptr<traversal_state> state;
196 std::default_sentinel_t end()
const {
201 const GraphWrapper* graph;
205template <
typename NodeID,
typename EdgeWeight,
bool Directed,
typename EdgeRange>
206Graph<NodeID, EdgeWeight, Directed> build_tree_from_edges(
const NodeID& root,
const EdgeRange& edges) {
207 Graph<NodeID, EdgeWeight, Directed> tree;
209 for (
const auto& [u, v] : edges) {
227 template <
typename... Args>
228 void examine_vertex(Args&&...) {}
230 template <
typename... Args>
231 void tree_edge(Args&&...) {}
233 template <
typename... Args>
234 void back_edge(Args&&...) {}
240template <
typename GraphWrapper,
typename Edge>
243 using NodeID =
typename GraphWrapper::NodeType;
245 GenericBfsEdgeVisitor(std::vector<std::pair<NodeID, NodeID>>& edges,
const GraphWrapper& graph_wrapper)
246 : tree_edges(edges), graph_wrapper(graph_wrapper) {}
248 template <
typename G>
249 void tree_edge(Edge e,
const G& g) {
250 NodeID u = graph_wrapper.get_node_id(boost::source(e, g));
251 NodeID v = graph_wrapper.get_node_id(boost::target(e, g));
252 tree_edges.emplace_back(u, v);
255 std::vector<std::pair<NodeID, NodeID>>& tree_edges;
256 const GraphWrapper& graph_wrapper;
259template <
typename GraphWrapper>
267[[deprecated(
"Use G.bfs_edges(start) instead.")]]
268auto bfs_edges(
const GraphWrapper& G,
const typename GraphWrapper::NodeType& start) {
269 return G.bfs_edges(start);
272template <
typename GraphWrapper>
280[[deprecated(
"Use G.bfs_tree(start) instead.")]]
281auto bfs_tree(
const GraphWrapper& G,
const typename GraphWrapper::NodeType& start) {
282 return G.bfs_tree(start);
285template <
typename GraphWrapper>
293[[deprecated(
"Use G.bfs_successors(start) instead.")]]
294auto bfs_successors(
const GraphWrapper& G,
const typename GraphWrapper::NodeType& start) {
295 return G.bfs_successors(start);
298template <
typename GraphWrapper,
typename Edge,
typename OnVertex,
typename OnTreeEdge>
301 using NodeID =
typename GraphWrapper::NodeType;
304 : graph_wrapper(graph_wrapper), on_vertex(on_vertex), on_tree_edge(on_tree_edge) {}
306 template <
typename G>
307 void examine_vertex(
typename boost::graph_traits<G>::vertex_descriptor u,
const G&)
const {
308 on_vertex(graph_wrapper.get_node_id(u));
311 template <
typename G>
312 void tree_edge(Edge e,
const G& g)
const {
313 on_tree_edge(graph_wrapper.get_node_id(boost::source(e, g)), graph_wrapper.get_node_id(boost::target(e, g)));
317 const GraphWrapper& graph_wrapper;
319 OnTreeEdge& on_tree_edge;
322template <
typename Visitor,
typename NodeID,
typename GraphWrapper>
323void bfs_dispatch_examine_vertex(Visitor&
visitor,
const NodeID& u,
const GraphWrapper& G) {
324 if constexpr (
requires {
visitor.examine_vertex(u, G); }) {
325 visitor.examine_vertex(u, G);
329template <
typename Visitor,
typename NodeID,
typename GraphWrapper>
330void bfs_dispatch_tree_edge(Visitor& visitor,
const NodeID& u,
const NodeID& v,
const GraphWrapper& G) {
331 if constexpr (
requires { visitor.tree_edge(u, v, G); }) {
332 visitor.tree_edge(u, v, G);
336template <
typename NodeID,
typename Edge,
typename GraphWrapper,
typename Visitor>
342 template <
typename G>
343 void examine_vertex(
typename boost::graph_traits<G>::vertex_descriptor u,
const G&)
const {
344 bfs_dispatch_examine_vertex(
visitor, graph_wrapper.get_node_id(u), graph_wrapper);
347 template <
typename G>
348 void tree_edge(Edge e,
const G& g)
const {
349 bfs_dispatch_tree_edge(
351 graph_wrapper.get_node_id(boost::source(e, g)),
352 graph_wrapper.get_node_id(boost::target(e, g)),
358 const GraphWrapper& graph_wrapper;
362template <
typename GraphWrapper,
typename Visitor>
370[[deprecated(
"Use G.breadth_first_search(start, visitor) instead.")]]
372 G.breadth_first_search(start,
visitor);
375template <
typename GraphWrapper,
typename OnVertex,
typename OnTreeEdge>
384[[deprecated(
"Use G.bfs_visit(start, on_vertex, on_tree_edge) instead.")]]
385void bfs_visit(
const GraphWrapper& G,
const typename GraphWrapper::NodeType& start, OnVertex&& on_vertex, OnTreeEdge&& on_tree_edge) {
386 G.bfs_visit(start, std::forward<OnVertex>(on_vertex), std::forward<OnTreeEdge>(on_tree_edge));
389template <
typename GraphWrapper,
typename Edge>
392 using NodeID =
typename GraphWrapper::NodeType;
394 GenericDfsEdgeVisitor(std::vector<std::pair<NodeID, NodeID>>& edges,
const GraphWrapper& graph_wrapper)
395 : tree_edges(edges), graph_wrapper(graph_wrapper) {}
397 template <
typename G>
398 void tree_edge(Edge e,
const G& g) {
399 NodeID u = graph_wrapper.get_node_id(boost::source(e, g));
400 NodeID v = graph_wrapper.get_node_id(boost::target(e, g));
401 tree_edges.emplace_back(u, v);
404 std::vector<std::pair<NodeID, NodeID>>& tree_edges;
405 const GraphWrapper& graph_wrapper;
408template <
typename GraphWrapper>
416[[deprecated(
"Use G.dfs_edges(start) instead.")]]
417auto dfs_edges(
const GraphWrapper& G,
const typename GraphWrapper::NodeType& start) {
418 return G.dfs_edges(start);
421template <
typename GraphWrapper>
429[[deprecated(
"Use G.dfs_tree(start) instead.")]]
430auto dfs_tree(
const GraphWrapper& G,
const typename GraphWrapper::NodeType& start) {
431 return G.dfs_tree(start);
434template <
typename GraphWrapper>
442[[deprecated(
"Use G.dfs_predecessors(start) instead.")]]
443auto dfs_predecessors(
const GraphWrapper& G,
const typename GraphWrapper::NodeType& start) {
444 return G.dfs_predecessors(start);
447template <
typename GraphWrapper>
455[[deprecated(
"Use G.dfs_successors(start) instead.")]]
456auto dfs_successors(
const GraphWrapper& G,
const typename GraphWrapper::NodeType& start) {
457 return G.dfs_successors(start);
460template <
typename GraphWrapper,
typename Edge,
typename OnTreeEdge,
typename OnBackEdge>
463 GenericDfsVisitVisitor(
const GraphWrapper& graph_wrapper, OnTreeEdge& on_tree_edge, OnBackEdge& on_back_edge)
464 : graph_wrapper(graph_wrapper), on_tree_edge(on_tree_edge), on_back_edge(on_back_edge) {}
466 template <
typename G>
467 void tree_edge(Edge e,
const G& g)
const {
468 on_tree_edge(graph_wrapper.get_node_id(boost::source(e, g)), graph_wrapper.get_node_id(boost::target(e, g)));
471 template <
typename G>
472 void back_edge(Edge e,
const G& g)
const {
473 on_back_edge(graph_wrapper.get_node_id(boost::source(e, g)), graph_wrapper.get_node_id(boost::target(e, g)));
477 const GraphWrapper& graph_wrapper;
478 OnTreeEdge& on_tree_edge;
479 OnBackEdge& on_back_edge;
482template <
typename Visitor,
typename NodeID,
typename GraphWrapper>
483void dfs_dispatch_tree_edge(Visitor&
visitor,
const NodeID& u,
const NodeID& v,
const GraphWrapper& G) {
484 if constexpr (
requires {
visitor.tree_edge(u, v, G); }) {
485 visitor.tree_edge(u, v, G);
489template <
typename Visitor,
typename NodeID,
typename GraphWrapper>
490void dfs_dispatch_back_edge(Visitor& visitor,
const NodeID& u,
const NodeID& v,
const GraphWrapper& G) {
491 if constexpr (
requires { visitor.back_edge(u, v, G); }) {
492 visitor.back_edge(u, v, G);
496template <
typename NodeID,
typename Edge,
typename GraphWrapper,
typename Visitor>
502 template <
typename G>
503 void tree_edge(Edge e,
const G& g)
const {
504 dfs_dispatch_tree_edge(
506 graph_wrapper.get_node_id(boost::source(e, g)),
507 graph_wrapper.get_node_id(boost::target(e, g)),
512 template <
typename G>
513 void back_edge(Edge e,
const G& g)
const {
514 dfs_dispatch_back_edge(
516 graph_wrapper.get_node_id(boost::source(e, g)),
517 graph_wrapper.get_node_id(boost::target(e, g)),
523 const GraphWrapper& graph_wrapper;
527template <
typename GraphWrapper,
typename Visitor>
535[[deprecated(
"Use G.depth_first_search(start, visitor) instead.")]]
537 G.depth_first_search(start,
visitor);
540template <
typename GraphWrapper,
typename OnTreeEdge,
typename OnBackEdge>
549[[deprecated(
"Use G.dfs_visit(start, on_tree_edge, on_back_edge) instead.")]]
550void dfs_visit(
const GraphWrapper& G,
const typename GraphWrapper::NodeType& start, OnTreeEdge&& on_tree_edge, OnBackEdge&& on_back_edge) {
551 G.dfs_visit(start, std::forward<OnTreeEdge>(on_tree_edge), std::forward<OnBackEdge>(on_back_edge));
554template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
556 std::vector<std::pair<NodeID, NodeID>> edges;
557 using EdgeType =
typename boost::graph_traits<GraphType>::edge_descriptor;
559 if (!has_node(start)) {
560 throw std::runtime_error(
"Traversal failed: start node not found.");
563 const auto start_bgl = get_id_to_bgl_map().at(start);
565 boost::breadth_first_search(get_impl(), start_bgl, boost::visitor(vis));
569template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
571 if (!has_node(start)) {
572 throw std::runtime_error(
"Traversal failed: start node not found.");
578template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
580 if (!has_node(start)) {
581 throw std::runtime_error(
"Traversal failed: start node not found.");
584 return detail::build_tree_from_edges<NodeID, EdgeWeight, Directed>(start,
bfs_edges(start));
587template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
589 if (!has_node(start))
throw std::runtime_error(
"Traversal failed: start node not found.");
590 std::vector<std::optional<std::vector<NodeID>>> successors(boost::num_vertices(g));
591 for (
const auto& [u, v] :
bfs_edges(start)) {
592 const auto parent_index = get_vertex_index(get_id_to_bgl_map().at(u));
593 if (!successors[parent_index].has_value()) {
594 successors[parent_index] = std::vector<NodeID>{};
596 successors[parent_index]->push_back(v);
598 return build_sparse_node_indexed_result<std::vector<NodeID>>(successors);
601template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
602template <
typename Visitor>
604 using EdgeType =
typename boost::graph_traits<GraphType>::edge_descriptor;
605 if (!has_node(start))
throw std::runtime_error(
"Traversal failed: start node not found.");
606 const auto start_bgl = get_id_to_bgl_map().at(start);
607 std::vector<boost::default_color_type> color(boost::num_vertices(g));
608 GenericBfsObjectVisitor<NodeID, EdgeType, Graph<NodeID, EdgeWeight, Directed, Multi, Weighted, OutEdgeSelector, VertexSelector>, Visitor> vis(*
this,
visitor);
609 boost::breadth_first_search(
612 boost::visitor(vis).color_map(boost::make_iterator_property_map(color.begin(), vertex_index_map))
616template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
617template <
typename OnVertex,
typename OnTreeEdge>
619 struct callback_visitor {
621 OnTreeEdge& on_tree_edge;
622 void examine_vertex(
const NodeID& u,
const Graph&) { on_vertex(u); }
623 void tree_edge(
const NodeID& u,
const NodeID& v,
const Graph&) { on_tree_edge(u, v); }
625 auto on_vertex_fn = std::forward<OnVertex>(on_vertex);
626 auto on_tree_edge_fn = std::forward<OnTreeEdge>(on_tree_edge);
627 callback_visitor
visitor{on_vertex_fn, on_tree_edge_fn};
631template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
633 std::vector<std::pair<NodeID, NodeID>> edges;
634 using EdgeType =
typename boost::graph_traits<GraphType>::edge_descriptor;
636 if (!has_node(start)) {
637 throw std::runtime_error(
"Traversal failed: start node not found.");
640 const auto start_bgl = get_id_to_bgl_map().at(start);
642 std::vector<boost::default_color_type> color(boost::num_vertices(g));
643 boost::depth_first_visit(
647 boost::make_iterator_property_map(color.begin(), vertex_index_map)
652template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
654 if (!has_node(start)) {
655 throw std::runtime_error(
"Traversal failed: start node not found.");
661template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
663 if (!has_node(start)) {
664 throw std::runtime_error(
"Traversal failed: start node not found.");
667 return detail::build_tree_from_edges<NodeID, EdgeWeight, Directed>(start,
dfs_edges(start));
670template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
672 if (!has_node(start))
throw std::runtime_error(
"Traversal failed: start node not found.");
673 std::vector<std::optional<NodeID>> predecessors(boost::num_vertices(g));
674 for (
const auto& [u, v] :
dfs_edges(start)) {
675 predecessors[get_vertex_index(get_id_to_bgl_map().at(v))] = u;
677 return build_sparse_node_indexed_result<NodeID>(predecessors);
680template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
682 if (!has_node(start))
throw std::runtime_error(
"Traversal failed: start node not found.");
683 std::vector<std::optional<std::vector<NodeID>>> successors(boost::num_vertices(g));
684 for (
const auto& [u, v] :
dfs_edges(start)) {
685 const auto parent_index = get_vertex_index(get_id_to_bgl_map().at(u));
686 if (!successors[parent_index].has_value()) {
687 successors[parent_index] = std::vector<NodeID>{};
689 successors[parent_index]->push_back(v);
691 return build_sparse_node_indexed_result<std::vector<NodeID>>(successors);
694template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
695template <
typename Visitor>
697 using EdgeType =
typename boost::graph_traits<GraphType>::edge_descriptor;
698 if (!has_node(start))
throw std::runtime_error(
"Traversal failed: start node not found.");
699 const auto start_bgl = get_id_to_bgl_map().at(start);
700 std::vector<boost::default_color_type> color(boost::num_vertices(g));
701 GenericDfsObjectVisitor<NodeID, EdgeType, Graph<NodeID, EdgeWeight, Directed, Multi, Weighted, OutEdgeSelector, VertexSelector>, Visitor> vis(*
this,
visitor);
702 boost::depth_first_visit(
706 boost::make_iterator_property_map(color.begin(), vertex_index_map)
710template <
typename NodeID,
typename EdgeWeight,
bool Directed,
bool Multi,
bool Weighted,
typename OutEdgeSelector,
typename VertexSelector>
711template <
typename OnTreeEdge,
typename OnBackEdge>
713 struct callback_visitor {
714 OnTreeEdge& on_tree_edge;
715 OnBackEdge& on_back_edge;
716 void tree_edge(
const NodeID& u,
const NodeID& v,
const Graph&) { on_tree_edge(u, v); }
717 void back_edge(
const NodeID& u,
const NodeID& v,
const Graph&) { on_back_edge(u, v); }
719 auto on_tree_edge_fn = std::forward<OnTreeEdge>(on_tree_edge);
720 auto on_back_edge_fn = std::forward<OnBackEdge>(on_back_edge);
721 callback_visitor
visitor{on_tree_edge_fn, on_back_edge_fn};
Definition traversal.hpp:241
Definition traversal.hpp:337
Definition traversal.hpp:299
Definition traversal.hpp:390
Definition traversal.hpp:497
Definition traversal.hpp:461
Graph wrapper around Boost Graph Library with Python-inspired helpers.
Definition graph.hpp:288
auto dfs_predecessors(const NodeID &start) const
Returns the DFS predecessor assigned to each discovered node.
Definition traversal.hpp:671
auto bfs_tree(const NodeID &start) const
Materializes the breadth-first-search tree rooted at start.
Definition traversal.hpp:579
auto bfs_edges_view(const NodeID &start) const
Returns a lazy input range over breadth-first-search tree edges.
Definition traversal.hpp:570
void bfs_visit(const NodeID &start, OnVertex &&on_vertex, OnTreeEdge &&on_tree_edge) const
Runs breadth-first search with lightweight callback hooks.
Definition traversal.hpp:618
auto dfs_edges_view(const NodeID &start) const
Returns a lazy input range over depth-first-search tree edges.
Definition traversal.hpp:653
void dfs_visit(const NodeID &start, OnTreeEdge &&on_tree_edge, OnBackEdge &&on_back_edge) const
Runs depth-first search with lightweight callback hooks.
Definition traversal.hpp:712
auto dfs_successors(const NodeID &start) const
Groups DFS tree children by their discovered parent.
Definition traversal.hpp:681
auto bfs_edges(const NodeID &start) const
Returns the tree edges discovered by breadth-first search.
Definition traversal.hpp:555
void depth_first_search(const NodeID &start, Visitor &visitor) const
Runs depth-first search with an object-style visitor.
Definition traversal.hpp:696
void breadth_first_search(const NodeID &start, Visitor &visitor) const
Runs breadth-first search with an object-style visitor.
Definition traversal.hpp:603
auto dfs_edges(const NodeID &start) const
Returns the tree edges discovered by depth-first search.
Definition traversal.hpp:632
auto bfs_successors(const NodeID &start) const
Groups BFS tree children by their discovered parent.
Definition traversal.hpp:588
auto dfs_tree(const NodeID &start) const
Materializes the depth-first-search tree rooted at start.
Definition traversal.hpp:662
Definition traversal.hpp:39
Definition traversal.hpp:32
Minimal visitor interface for wrapper-level traversal callbacks.
Definition traversal.hpp:225
Core graph wrapper, proxy surface, and public alias presets.
auto bfs_successors(const GraphWrapper &G, const typename GraphWrapper::NodeType &start)
Deprecated free-function alias for G.bfs_successors(start).
Definition traversal.hpp:294
void depth_first_search(const GraphWrapper &G, const typename GraphWrapper::NodeType &start, Visitor &visitor)
Deprecated free-function alias for G.depth_first_search(start, visitor).
Definition traversal.hpp:536
void dfs_visit(const GraphWrapper &G, const typename GraphWrapper::NodeType &start, OnTreeEdge &&on_tree_edge, OnBackEdge &&on_back_edge)
Deprecated free-function alias for G.dfs_visit(start, on_tree_edge, on_back_edge).
Definition traversal.hpp:550
auto dfs_successors(const GraphWrapper &G, const typename GraphWrapper::NodeType &start)
Deprecated free-function alias for G.dfs_successors(start).
Definition traversal.hpp:456
void breadth_first_search(const GraphWrapper &G, const typename GraphWrapper::NodeType &start, Visitor &visitor)
Deprecated free-function alias for G.breadth_first_search(start, visitor).
Definition traversal.hpp:371
auto dfs_tree(const GraphWrapper &G, const typename GraphWrapper::NodeType &start)
Deprecated free-function alias for G.dfs_tree(start).
Definition traversal.hpp:430
auto bfs_edges(const GraphWrapper &G, const typename GraphWrapper::NodeType &start)
Deprecated free-function alias for G.bfs_edges(start).
Definition traversal.hpp:268
auto dfs_predecessors(const GraphWrapper &G, const typename GraphWrapper::NodeType &start)
Deprecated free-function alias for G.dfs_predecessors(start).
Definition traversal.hpp:443
auto bfs_tree(const GraphWrapper &G, const typename GraphWrapper::NodeType &start)
Deprecated free-function alias for G.bfs_tree(start).
Definition traversal.hpp:281
auto dfs_edges(const GraphWrapper &G, const typename GraphWrapper::NodeType &start)
Deprecated free-function alias for G.dfs_edges(start).
Definition traversal.hpp:417
void bfs_visit(const GraphWrapper &G, const typename GraphWrapper::NodeType &start, OnVertex &&on_vertex, OnTreeEdge &&on_tree_edge)
Deprecated free-function alias for G.bfs_visit(start, on_vertex, on_tree_edge).
Definition traversal.hpp:385