简体   繁体   中英

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.

(eg

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

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

)

至少您必须在期望的位置传递属性映射:

.reverse_edge_map(make_assoc_property_map(reverse_edge_of))

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