【问题标题】:Boost graph clear_out_edges argument mismatchBoost graph clear_out_edges 参数不匹配
【发布时间】:2021-05-19 18:20:24
【问题描述】:

根据https://www.boost.org/doc/libs/1_37_0/libs/graph/doc/adjacency_list.html

clear_out_edges的声明是:

void clear_out_edges(vertex_descriptor u, adjacency_list& g)

我的文件中有以下内容:

typedef adjacency_list<
    vecS, vecS, directedS,

    property<
    vertex_name_t, std::string,
    property<vertex_index_t, int,
    property<vertex_color_t, boost::default_color_type,
    property<vertex_distance_t, double,
    property<vertex_predecessor_t, Traits::edge_descriptor>
    > > > >,

    property<
    edge_index_t, int,
    property<edge_capacity_t, double,
    property<edge_weight_t, double,
    property<edge_residual_capacity_t, double,
    property<edge_reverse_t, Traits::edge_descriptor>
> > > > >
Graph;

Graph g;

试图通过访问所有顶点来清除边缘:

Graph::vertex_iterator v, vend;
for(boost::tie(v, vend) = vertices(g); v != vend; ++v){
    boost::clear_out_edges(v, g);//line in question
}

编译器抱怨:

no instance of overloaded function "boost::clear_out_edges" matches the argument list -- argument types are: (boost::range_detail::integer_iterator&lt;std::size_t&gt;, Graph)C/C++(304)

我对此感到惊讶,因为 g 是通过 typedef 的 adjacency_list 类的对象。

感谢任何帮助。

【问题讨论】:

    标签: boost boost-graph


    【解决方案1】:

    您使用 v 就好像它是一个描述符,但它是一个迭代器。取消引用它:

    clear_out_edges(*v, g);
    

    我可以建议稍微现代化一下,也许使用捆绑属性而不是using namespace?从古老的文档样本中复制粘贴了太多代码,这些样本仍然可以在 c++03 上编译。

    Live On Wandbox

    #include <boost/graph/adjacency_list.hpp>
    using namespace boost;
    
    using Traits = adjacency_list_traits<vecS, vecS, directedS>;
    using Graph  = adjacency_list<
        vecS, vecS, directedS,
    
        property<vertex_name_t, std::string,
        property<vertex_index_t, int,
        property<vertex_color_t, boost::default_color_type,
        property<vertex_distance_t, double,
        property<vertex_predecessor_t,
         Traits::edge_descriptor>>>>>,
    
        property<edge_index_t, int,
        property<edge_capacity_t, double,
        property<edge_weight_t, double,
        property<edge_residual_capacity_t, double,
        property<edge_reverse_t,
         Traits::edge_descriptor>>>>>>;
    
    int main()
    {
        Graph g(10);
        for (auto v : boost::make_iterator_range(vertices(g))) {
            clear_out_edges(v, g);
        }
    }
    

    或者更好,取决于口味。请注意,至少vertex_indexvecS 是非常多余的,并且可能会严重损害您的代码正确性。

    更新

    关于现代化代码的一些提示,以及可能将图形模型与算法特定的元数据分开。

    Live On Wandbox

    #include <boost/graph/adjacency_list.hpp>
    #include <boost/graph/edmonds_karp_max_flow.hpp>
    #include <boost/graph/boykov_kolmogorov_max_flow.hpp>
    
    struct VertexProps { std::string name; };
    struct EdgeProps { double capacity = 0, weight = 0, residual = 0; };
    
    using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
                                        VertexProps, EdgeProps>;
    
    using V = Graph::vertex_descriptor;
    using E = Graph::edge_descriptor;
    
    int main()
    {
        Graph g(10);
        for (auto v : boost::make_iterator_range(vertices(g))) {
            clear_out_edges(v, g);
        }
    
        auto idmap = get(boost::vertex_index, g);
        std::vector<boost::default_color_type> colors(num_vertices(g));
        std::vector<E> predecessors(num_vertices(g));
        std::vector<double> distances(num_vertices(g));
    
        auto weightmap = get(&EdgeProps::weight, g);
        auto capacity_map = get(&EdgeProps::capacity, g);
        auto residual_map = get(&EdgeProps::residual, g);
    
        std::map<E, E> reverse_edges;
    
        V src  = 0;
        V sink = 1;
    
        boost::edmonds_karp_max_flow(
            g, src, sink,
            boost::color_map(colors.data())
                .vertex_index_map(idmap)
                .distance_map(distances.data())
                .predecessor_map(predecessors.data())
                .weight_map(weightmap)
                .capacity_map(capacity_map)
                .residual_capacity_map(residual_map)
                .reverse_edge_map(boost::make_assoc_property_map(reverse_edges)));
    }
    

    请记住,boykov_kolmogorov_max_flow 存在一个已知问题(请参阅 Boost max flow algorithms do not compile. error: forming reference to voidhttps://github.com/boostorg/graph/issues/232)。

    【讨论】:

    • 感谢您一如既往的详细解答。我确实在研究最大流量问题,您提供的示例非常中肯。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    相关资源
    最近更新 更多