简体   繁体   中英

boost DFS does not work with setS vertice lists

The following code is not compiled.

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/topological_sort.hpp>
#include <boost/function_output_iterator.hpp>

typedef boost::adjacency_list<
    boost::setS, // outedge list
    boost::setS, // vertex list
    boost::directedS, // undirected 
    boost::no_property, // vertex prop
    boost::no_property, // edge prop
    boost::no_property, // graph prop
    boost::setS // edgelist
> Graph;

bool hasCycle(const Graph& aG) 
{
    try {
        boost::topological_sort(
            aG, 
            boost::make_function_output_iterator([](int){}));
    } catch(boost::not_a_dag const&)
    {
        return true;
    }
    return false;
 } 

It works after changing vertice lists to be vecS http://coliru.stacked-crooked.com/a/abeb9e3f96e92af0

Is this limitation because DFS needs a deterministic visits?

Thank you,

The "limitation" is documented as the need for a vertex index. You could add one (note that you also should replace int by Graph::vertex_descriptor ), or adjust the graph type to include one:

Adding an external index property map

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/topological_sort.hpp>
#include <boost/function_output_iterator.hpp>

typedef boost::adjacency_list<
    boost::setS, // outedge list
    boost::setS, // vertex list
    boost::directedS, // undirected 
    boost::no_property, // vertex prop
    boost::no_property, // edge prop
    boost::no_property, // graph prop
    boost::setS // edgelist
> Graph;

bool hasCycle(const Graph& aG)
{
    try {
        std::map<Graph::vertex_descriptor, size_t> index;
        auto pmap = boost::make_assoc_property_map(index);

        for (auto vd : boost::make_iterator_range(boost::vertices(aG)))
            index[vd] = index.size();

        boost::topological_sort(
            aG,
            boost::make_function_output_iterator([](Graph::vertex_descriptor){}),
            boost::vertex_index_map(pmap));
    }
    catch (boost::not_a_dag const&)
    {
        return true;
    }
    return false;
}

int main() {
}

Adding an internal index property map

This amounts to shifting the burden to the caller. This might make (a lot of) sense depending on the performance requirements for you application.

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/topological_sort.hpp>
#include <boost/function_output_iterator.hpp>

typedef boost::adjacency_list<
    boost::setS, // outedge list
    boost::setS, // vertex list
    boost::directedS, // undirected 
    boost::property<boost::vertex_index_t, int>, // vertex prop
    boost::no_property, // edge prop
    boost::no_property, // graph prop
    boost::setS // edgelist
> Graph;

bool hasCycle(const Graph& aG)
{
    try {
        boost::topological_sort(
            aG,
            boost::make_function_output_iterator([](Graph::vertex_descriptor){})
        );
    }
    catch (boost::not_a_dag const&)
    {
        return true;
    }
    return false;
}

#include <boost/graph/random.hpp>
#include <random>

int main() {
    std::mt19937 prng{ std::random_device{}() };
    Graph g;
    boost::generate_random_graph(g, 100, 200, prng);
    auto index = boost::get(boost::vertex_index, g);

    int gen_id = 0;
    for (auto vd : boost::make_iterator_range(boost::vertices(g))) {
        boost::put(index, vd, gen_id++);
        std::cout << "Vertex " << boost::get(index, vd) << "\n";
    }

    bool check = hasCycle(g);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM