Boost provides three different algorithms for finding max flow in directed graphs: boykov_kolmogorov, edmonds_karp and push_relabel. All of them have named and non-named parameter versions. Parameter sets they use are also very similar. Despite that, with same parameters some of these algorithms compile and some of them do not.
push_relabel compiles nicely with both named and non-named version:
using Graph =
boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
VertexProperty, EdgeProperty>;
auto props = boost::capacity_map(capacity)
.residual_capacity_map(residual_capacity)
.reverse_edge_map(reverse_edge_map)
.vertex_index_map(vertex_index_map)
.color_map(color_map)
.predecessor_map(predcessor_map)
.distance_map(distance_map);
boost::push_relabel_max_flow(g, s, t, props);
boost::push_relabel_max_flow(g, s, t, capacity, residual_capacity,
reverse_edge_map, vertex_index_map);
boykov_kolmogorov compiles with non-named version:
boost::boykov_kolmogorov_max_flow(g, capacity, residual_capacity,
reverse_edge_map,
vertex_index_map, s, t);
But fails with named version:
boost::boykov_kolmogorov_max_flow(g, s, t, props);
/celibs/boost_1_73_0/boost/graph/detail/adjacency_list.hpp:2768:17: error: forming reference to void
edmonds_karp fails with both named and non-named versions with same error:
boost::edmonds_karp_max_flow(g, s, t, props);
boost::edmonds_karp_max_flow(g, s, t, capacity, residual_capacity, reverse_edge_map,
color_map, predcessor_map);
/celibs/boost_1_73_0/boost/concept_check.hpp:147:9: error: use of deleted function
Full example is here: https://godbolt.org/z/dvjfec
Do I pass parameters in incorrect way? How to pass them correctly?
Thanks!
This indeed seems to be a bug.
It appears that the
choose_const_pmap
foredge_capacity
fails when there is no interioredge_capacity_t
property defined (Interior Properties).Defining one makes the problem go away. However, we can check that it always takes precedence over the one provided via named paramaters:
Leads to compilation problems, suggesting that the wrong property map is selected.
I could not find an obvious cause for this behaviour - all the other named arguments behave as expected, and are declared in very similar fashion (the process is automated by macro). I assume there will be something very subtle involved (like a name collision or ADL mishap?).
Here's the code that works for me:
Live On Wandbox (note obviously can't run successfully, because it doesn't satisfy any invariants)
As you can see all of the algorithm invocations now compile.