Tryer
Tryer

Reputation: 4110

Boost graph clear_out_edges argument mismatch

According to https://www.boost.org/doc/libs/1_37_0/libs/graph/doc/adjacency_list.html

the declaration of clear_out_edges is:

void clear_out_edges(vertex_descriptor u, adjacency_list& g)

I have the following in my file:

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;

In trying to clear the edges by visiting all of the vertices via:

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

the compiler complains that:

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)

I am surprised by this, since g is an object of class adjacency_list via the typedef.

Any help is appreciated.

Upvotes: 1

Views: 70

Answers (1)

sehe
sehe

Reputation: 394054

You're using v as if it is a descriptor, but it's an iterator. Dereference it:

clear_out_edges(*v, g);

May I suggest modernizing a bit, and perhaps using bundled properties and less using namespace? Too much code is being copy-pasted from ancient documentation samples which are written to still compile on 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);
    }
}

Or even better, depending on tastes. Note that at least vertex_index is very redundant with vecS and may actively harm your code correctness.

UPDATE

Some hints about modernizing the code, and perhaps separating the graph model from algorithm specific metadata.

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 Boost max flow algorithms do not compile. error: forming reference to void and https://github.com/boostorg/graph/issues/232).

Upvotes: 1

Related Questions