Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to allow breadth_first_search to use in_edges #365

Open
byjtew opened this issue Feb 21, 2024 · 0 comments
Open

Option to allow breadth_first_search to use in_edges #365

byjtew opened this issue Feb 21, 2024 · 0 comments

Comments

@byjtew
Copy link

byjtew commented Feb 21, 2024

Context: You want to create a predecessors(source_node) function gathering the vertices that point to a given source_vertex, you'd want to use a BFS visitor, which is currently impossible since the usage of the out_edges iterator is hardcoded in its behaviour.

Feature request: A new function inv_breadth_first_search, or an extra template parameter to specify which iterator to use (in_edges/out_edges)

Here's the local version that we use:

template<class IncidenceGraph, class Buffer, class BFSVisitor, class ColorMap, class SourceIterator>
void inv_breadth_first_visit(const IncidenceGraph &g, SourceIterator sources_begin, SourceIterator sources_end,
                             Buffer &Q, BFSVisitor vis, ColorMap color) {
    BOOST_CONCEPT_ASSERT((IncidenceGraphConcept<IncidenceGraph>));
    typedef graph_traits<IncidenceGraph> GTraits;
    typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
    BOOST_CONCEPT_ASSERT((BFSVisitorConcept<BFSVisitor, IncidenceGraph>));
    BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept<ColorMap, Vertex>));
    typedef typename property_traits<ColorMap>::value_type ColorValue;
    typedef color_traits<ColorValue> Color;
    typename GTraits::in_edge_iterator ei, ei_end;

    for (; sources_begin != sources_end; ++sources_begin) {
        Vertex s = *sources_begin;
        put(color, s, Color::gray());
        vis.discover_vertex(s, g);
        Q.push(s);
    }
    while (!Q.empty()) {
        Vertex u = Q.top();
        Q.pop();
        vis.examine_vertex(u, g);
        for (boost::tie(ei, ei_end) = in_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);
                put(color, v, Color::gray());
                vis.discover_vertex(v, g);
                Q.push(v);
            } else {
                vis.non_tree_edge(*ei, g);
                if (v_color == Color::gray())
                    vis.gray_target(*ei, g);
                else
                    vis.black_target(*ei, g);
            }
        } // end for
        put(color, u, Color::black());
        vis.finish_vertex(u, g);
    } // end while
}

cc @raphael-s-steiner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant