提升图 clear_out_edges 参数不匹配

Boost graph clear_out_edges argument mismatch

根据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<std::size_t>, Graph)C/C++(304)

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

感谢任何帮助。

您正在使用 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)));
}

Keep in mind that there's a known issue with boykov_kolmogorov_max_flow (see and https://github.com/boostorg/graph/issues/232).