--- depth_first_search.hpp.orig 2018-02-23 22:45:42.000000000 -0700 +++ depth_first_search.hpp 2018-07-09 10:33:34.000000000 -0600 @@ -107,6 +107,82 @@ template void depth_first_visit_impl + (IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor& vis, + ColorMap color, TerminatorFunc func = TerminatorFunc()) + { + BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); + BOOST_CONCEPT_ASSERT(( DFSVisitorConcept )); + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); + typedef typename property_traits::value_type ColorValue; + BOOST_CONCEPT_ASSERT(( ColorValueConcept )); + typedef color_traits Color; + typedef typename graph_traits::out_edge_iterator Iter; + typedef std::pair, std::pair > > VertexInfo; + + boost::optional src_e; + Iter ei, ei_end; + std::vector stack; + + // Possible optimization for vector + //stack.reserve(num_vertices(g)); + + put(color, u, Color::gray()); + vis.discover_vertex(u, g); + boost::tie(ei, ei_end) = out_edges(u, g); + if (func(u, g)) { + // If this vertex terminates the search, we push empty range + stack.push_back(std::make_pair(u, std::make_pair(boost::optional(), std::make_pair(ei_end, ei_end)))); + } else { + stack.push_back(std::make_pair(u, std::make_pair(boost::optional(), std::make_pair(ei, ei_end)))); + } + while (!stack.empty()) { + VertexInfo& back = stack.back(); + u = back.first; + src_e = back.second.first; + boost::tie(ei, ei_end) = back.second.second; + stack.pop_back(); + // finish_edge has to be called here, not after the + // loop. Think of the pop as the return from a recursive call. + if (src_e) { + call_finish_edge(vis, src_e.get(), g); + } + while (ei != ei_end) { + Vertex v = target(*ei, g); + vis.examine_edge(*ei, g); + ColorValue v_color = get(color, v); + if (v_color == Color::white()) { + vis.tree_edge(*ei, g); + src_e = *ei; + stack.push_back(std::make_pair(u, std::make_pair(src_e, std::make_pair(++ei, ei_end)))); + u = v; + put(color, u, Color::gray()); + vis.discover_vertex(u, g); + boost::tie(ei, ei_end) = out_edges(u, g); + if (func(u, g)) { + ei = ei_end; + } + } else { + if (v_color == Color::gray()) { + vis.back_edge(*ei, g); + } else { + vis.forward_or_cross_edge(*ei, g); + } + call_finish_edge(vis, *ei, g); + ++ei; + } + } + put(color, u, Color::black()); + vis.finish_vertex(u, g); + } + } + + template + void depth_first_visit_impl (const IncidenceGraph& g, typename graph_traits::vertex_descriptor u, DFSVisitor& vis, @@ -185,6 +261,38 @@ template void depth_first_visit_impl + (IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor& vis, // pass-by-reference here, important! + ColorMap color, TerminatorFunc func) + { + BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); + BOOST_CONCEPT_ASSERT(( DFSVisitorConcept )); + typedef typename graph_traits::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); + typedef typename property_traits::value_type ColorValue; + BOOST_CONCEPT_ASSERT(( ColorValueConcept )); + typedef color_traits Color; + typename graph_traits::out_edge_iterator ei, ei_end; + + put(color, u, Color::gray()); vis.discover_vertex(u, g); + + if (!func(u, g)) + for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { + Vertex v = target(*ei, g); vis.examine_edge(*ei, g); + ColorValue v_color = get(color, v); + if (v_color == Color::white()) { vis.tree_edge(*ei, g); + depth_first_visit_impl(g, v, vis, color, func); + } else if (v_color == Color::gray()) vis.back_edge(*ei, g); + else vis.forward_or_cross_edge(*ei, g); + call_finish_edge(vis, *ei, g); + } + put(color, u, Color::black()); vis.finish_vertex(u, g); + } + + template + void depth_first_visit_impl (const IncidenceGraph& g, typename graph_traits::vertex_descriptor u, DFSVisitor& vis, // pass-by-reference here, important! @@ -220,6 +328,36 @@ template void + depth_first_search(VertexListGraph& g, DFSVisitor vis, ColorMap color, + typename graph_traits::vertex_descriptor start_vertex) + { + typedef typename graph_traits::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT(( DFSVisitorConcept )); + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + + typename graph_traits::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { + Vertex u = implicit_cast(*ui); + put(color, u, Color::white()); vis.initialize_vertex(u, g); + } + + if (start_vertex != detail::get_default_starting_vertex(g)){ vis.start_vertex(start_vertex, g); + detail::depth_first_visit_impl(g, start_vertex, vis, color, + detail::nontruth2()); + } + + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { + Vertex u = implicit_cast(*ui); + ColorValue u_color = get(color, u); + if (u_color == Color::white()) { vis.start_vertex(u, g); + detail::depth_first_visit_impl(g, u, vis, color, detail::nontruth2()); + } + } + } + + template + void depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color, typename graph_traits::vertex_descriptor start_vertex) { @@ -250,6 +388,18 @@ template void + depth_first_search(VertexListGraph& g, DFSVisitor vis, ColorMap color) + { + typedef typename boost::graph_traits::vertex_iterator vi; + std::pair verts = vertices(g); + if (verts.first == verts.second) + return; + + depth_first_search(g, vis, color, detail::get_default_starting_vertex(g)); + } + + template + void depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color) { typedef typename boost::graph_traits::vertex_iterator vi; @@ -267,38 +417,74 @@ dfs_visitor(Visitors vis) : m_vis(vis) { } template + void initialize_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex()); + } + template void initialize_vertex(Vertex u, const Graph& g) { invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex()); } template + void start_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_start_vertex()); + } + template void start_vertex(Vertex u, const Graph& g) { invoke_visitors(m_vis, u, g, ::boost::on_start_vertex()); } template + void discover_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex()); + } + template void discover_vertex(Vertex u, const Graph& g) { invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex()); } template + void examine_edge(Edge u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_examine_edge()); + } + template void examine_edge(Edge u, const Graph& g) { invoke_visitors(m_vis, u, g, ::boost::on_examine_edge()); } template + void tree_edge(Edge u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_tree_edge()); + } + template void tree_edge(Edge u, const Graph& g) { invoke_visitors(m_vis, u, g, ::boost::on_tree_edge()); } template + void back_edge(Edge u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_back_edge()); + } + template void back_edge(Edge u, const Graph& g) { invoke_visitors(m_vis, u, g, ::boost::on_back_edge()); } template + void forward_or_cross_edge(Edge u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_forward_or_cross_edge()); + } + template void forward_or_cross_edge(Edge u, const Graph& g) { invoke_visitors(m_vis, u, g, ::boost::on_forward_or_cross_edge()); } template + void finish_edge(Edge u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_finish_edge()); + } + template void finish_edge(Edge u, const Graph& g) { invoke_visitors(m_vis, u, g, ::boost::on_finish_edge()); } template + void finish_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex()); + } + template void finish_vertex(Vertex u, const Graph& g) { invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex()); } @@ -346,6 +532,16 @@ template void depth_first_visit + (IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor vis, ColorMap color) + { + vis.start_vertex(u, g); + detail::depth_first_visit_impl(g, u, vis, color, detail::nontruth2()); + } + + template + void depth_first_visit (const IncidenceGraph& g, typename graph_traits::vertex_descriptor u, DFSVisitor vis, ColorMap color) @@ -357,6 +553,17 @@ template void depth_first_visit + (IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor vis, ColorMap color, TerminatorFunc func = TerminatorFunc()) + { + vis.start_vertex(u, g); + detail::depth_first_visit_impl(g, u, vis, color, func); + } + + template + void depth_first_visit (const IncidenceGraph& g, typename graph_traits::vertex_descriptor u, DFSVisitor vis, ColorMap color, TerminatorFunc func = TerminatorFunc())