使用BGL的BFS算法使用多个访问者

时间:2015-12-24 18:51:43

标签: boost graph breadth-first-search boost-graph

trying使用BGL的BFS算法使用两个访问者:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/visitors.hpp>

using Graph = boost::adjacency_list<>;
using Vertex = Graph::vertex_descriptor;
using Edge = Graph::edge_descriptor;

namespace boost 
{
    template <typename event_type>
    class test_visitor: public default_bfs_visitor 
    {
        public:
            using event_filter = event_type;
            void discover_vertex(Vertex, const Graph&) const 
            {
                std::cout << "vertex discovered" << std::endl;
            }
    };
}

int main() 
{

    // Initialize a test graph
    Graph graph;
    Vertex vertexFoo = boost::add_vertex(graph);
    Vertex vertexBar = boost::add_vertex(graph);
    Vertex vertexBaz = boost::add_vertex(graph);
    boost::add_edge(vertexFoo, vertexBar, graph);
    boost::add_edge(vertexBar, vertexBaz, graph);

    // Initialize parents map
    std::vector<Vertex> parents_map(boost::num_vertices(graph));
    parents_map[vertexFoo] = vertexFoo;

    // Perform BFS with two listeners
    boost::breadth_first_search(
        graph,
        vertexFoo,
        boost::visitor(
            boost::make_bfs_visitor(
                std::make_pair(
                    boost::record_predecessors(&parents_map[0], boost::on_tree_edge()),
                    boost::test_visitor<boost::on_discover_vertex()>()
                )
            )
        )
    );

    return 0;
}

我的自定义访问者的监听器(discover_vertex)由于某种原因未被调用。我认为这个问题与我如何将听众传递给breadth_first_search有关。我无法找到关于boost::visitorboost::make_bfs_visitor的好文档。

B.t.w。我的自定义访问者可以正常工作,如果我从中移除using event_filter = event_type;并将其包含在仅boost::visitor而不包含boost::make_bfs_visitor的{​​{1}}中,这需要typedef

我也无法找到任何关于event_filter的文档以及如何在一个访问者中同时使用多个事件(例如on_discover_vertexon_examine_edge)。我是否正确event_filter指定访问者将处理哪些事件?有关此文档的链接值得赞赏。

1 个答案:

答案 0 :(得分:2)

首先,无需在boost名称空间中声明访问者。这是一个坏主意,不要将自己的东西注入你无法控制的名称空间。

接下来,如果您使用make_bfs_visitor拼凑特定event_filter的访问者,则需要实施operator()而不是discover_vertex

template <typename event_type>
struct test_visitor: public default_bfs_visitor 
{
    using event_filter = event_type;

    void operator()(Vertex, Graph const&) const {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

最后,event_type参数完全错误,请删除括号:

test_visitor<boost::on_discover_vertex>()

样本

<强> Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/visitors.hpp>
#include <iostream>

using Graph  = boost::adjacency_list<>;
using Vertex = Graph::vertex_descriptor;
using Edge   = Graph::edge_descriptor;

template <typename event_type>
struct test_visitor: public boost::default_bfs_visitor {
    using event_filter = event_type;

    void operator()(Vertex, Graph const&) const {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

int main() {
    // Initialize a test graph
    enum { Foo, Bar, Baz, NUMVERTICES };
    Graph graph(NUMVERTICES);
    boost::add_edge(Foo, Bar, graph);
    boost::add_edge(Bar, Baz, graph);

    // Initialize parents map
    std::vector<Vertex> parents_map(boost::num_vertices(graph));
    parents_map[Foo] = Foo;

    // Perform BFS with two listeners
    boost::breadth_first_search(graph, Foo,
        boost::visitor(
            boost::make_bfs_visitor(
                std::make_pair(
                    boost::record_predecessors(&parents_map[0], boost::on_tree_edge()),
                    test_visitor<boost::on_discover_vertex>()
                )
            )
        )
    );
}