User1291
User1291

Reputation: 8229

BGL - using flow algorithms with bundled properties

I cannot seem to figure out how to get BGL's push-relabel max flow algorithm to work with bundled properties.

Setting up the graph like this:

struct VertexProperties{

};

struct EdgeProperties{
    int id;
    int capacity;
    int residual_capacity;
};

typedef boost::adjacency_list<vecS,vecS,directedS,VertexProperties,EdgeProperties> Graph;
typedef boost::graph_traits<Graph> Traits;
typedef Traits::vertex_descriptor Vertex;
typedef Traits::edge_descriptor Edge;

I create a

Graph g(nofNodes); // nofNodes > 2

and choose

Vertex s = vertex(nofNodes-2,g); //source
Vertex t = vertex(nofNodes-1,g); //sink

I then proceed to add edges to the graph and add reverse edges of capacity 0 for each edge inserted.

Using a map

std::map<Edge,Edge> reverse_edge_of;

and

void do_add_edge(int& next_id, const Vertex& a, const Vertex& b, const int c, Graph& g,std::map<Edge,Edge>& reverse_edge_of){
    Edge e,re; bool success;

    std::tie(e,success) = add_edge(a,b,g);
    g[e].id = next_id;
    g[e].capacity = c;
    g[e].residual_capacity = c;

    //reverse edge
    std::tie(re,success) = add_edge(b,a,g);
    g[re].id = next_id + 1;
    g[re].capacity = 0;
    g[re].residual_capacity = 0;

    reverse_edge_of[e] = re;
    reverse_edge_of[re] = e;

    next_id += 2;
}

After that's done, I try to call the library function push_relabel_max_flow like this:

push_relabel_max_flow(
    g,
    s,
    t,
    capacity_map(get(&EdgeProperties::capacity,g))
    .residual_capacity_map(get(&EdgeProperties::residual_capacity,g))
    .reverse_edge_map(make_assoc_property_map(reverse_edge_of))
    .vertex_index_map(get(vertex_index,g))
);

This fails to compile (with a very unreadable error message).

Unfortunately, the example provided by the documentation is still using the internal properties it has labeled deprecated itself, so I'm struggling to find the error in my approach. Does anybody happen to see it?

And while we're at it (and as it is quite possibly related), can I somehow make an edge's reverse edge a (part of the bundled!) edge property? If so, how?

UPDATE

No idea what's going on here, but it turns out

        int maxflow = push_relabel_max_flow(
            g,
            s,
            t,
            capacity_map(get(&EdgeProperties::capacity,g))
            .residual_capacity_map(get(&EdgeProperties::residual_capacity,g))
            .reverse_edge_map(make_assoc_property_map(reverse_edge_of))
            .vertex_index_map(get(vertex_index,g))
        );

will produce the error, whereas

        int maxflow = push_relabel_max_flow(
            g,
            s,
            t,
            get(&EdgeProperties::capacity,g),
            get(&EdgeProperties::residual_capacity,g),
            make_assoc_property_map(reverse_edge_of),
            get(vertex_index,g)
        );

does not.

(e.g.

works as intended: http://ideone.com/U3O0p8

compiler error: http://ideone.com/uUuiKc

)

Upvotes: 1

Views: 173

Answers (1)

sehe
sehe

Reputation: 393829

At the very least you have to pass in the propertymap where expected:

.reverse_edge_map(make_assoc_property_map(reverse_edge_of))

Upvotes: 1

Related Questions