问题描述
Boost提供了三种用于在有向图中查找最大流量的算法: boykov_kolmogorov , edmonds_karp 和 push_relabel 。它们都有命名和未命名的参数版本。他们使用的参数集也非常相似。尽管如此,使用相同的参数,其中一些算法可以编译,而有些则不能。
push_relabel 可以很好地编译命名和未命名版本:
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,capacity,residual_capacity,reverse_edge_map,vertex_index_map);
boykov_kolmogorov 使用非命名版本进行编译:
boost::boykov_kolmogorov_max_flow(g,vertex_index_map,t);
但使用命名版本失败:
boost::boykov_kolmogorov_max_flow(g,props);
/celibs/boost_1_73_0/boost/graph/detail/adjacency_list.hpp:2768:17:错误:形成对void的引用
edmonds_karp 失败,命名和未命名版本均出现相同错误:
boost::edmonds_karp_max_flow(g,props);
boost::edmonds_karp_max_flow(g,color_map,predcessor_map);
/celibs/boost_1_73_0/boost/concept_check.hpp:147:9:错误:使用已删除的功能
完整的示例在这里:https://godbolt.org/z/dvjfec
我是否以错误的方式传递参数?如何正确传递它们?
谢谢!
解决方法
这确实是一个错误。
似乎没有定义内部choose_const_pmap
属性(Interior Properties)时edge_capacity
的{{1}}失败。
定义一个使问题消失。但是,我们可以检查它始终优先于通过命名参数提供的优先级:
edge_capacity_t
导致编译问题,表明选择了错误的属性映射。
我找不到导致这种现象的明显原因-所有其他命名参数的行为均符合预期,并且以非常相似的方式声明(该过程由宏自动执行)。我认为会涉及到非常微妙的东西(例如名称冲突或ADL事故?)。
以下是对我有用的代码:
Live On Wandbox (请注意显然无法成功运行,因为它不能满足任何不变式)
struct Oops {};
using EdgeProperty = boost::property<boost::edge_capacity_t,Oops>;
如您所见,所有算法调用现在都已编译。