Boost最大流量算法不编译.错误:形成对void的引用



Boost提供了三种不同的算法来寻找有向图中的最大流:boykov_kolmogorovedmonds_karppush_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, s, t, capacity, residual_capacity,
reverse_edge_map, vertex_index_map);

boykov_kolmogorov使用非命名版本编译:

boost::boykov_kolmogorov_max_flow(g, capacity, residual_capacity,
reverse_edge_map,
vertex_index_map, s, t);

但命名版本失败:

boost::boykov_kolmogorov_max_flow(g, s, t, props);

/cilibs/brust_1_7\3_0/boost/graph/detail/adjacety_list.hpp:2768:17:错误:形成无效的参考

edmonds_karp在命名和非命名版本中都失败,错误相同:

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);

/clibs/boost_1_73_0/boostconcept_check.hpp:147:9:错误:使用已删除的函数

完整示例如下:https://godbolt.org/z/dvjfec

我是否以错误的方式传递参数?如何正确传递?

谢谢!

这确实是一个bug。

当没有定义内部edge_capacity_t属性(内部属性(时,edge_capacitychoose_const_pmap似乎会失败。

定义一个会使问题消失。然而,我们可以检查它是否总是优先于通过命名参数提供的参数:

struct Oops {};
using EdgeProperty = boost::property<boost::edge_capacity_t, Oops>;

导致编译问题,表明选择了错误的属性映射。

我找不到导致这种行为的明显原因——所有其他命名的参数都按预期运行,并且以非常相似的方式声明(该过程由宏自动执行(。我想会有一些非常微妙的事情发生(比如名字冲突或ADL事故?(。

以下是适用于我的代码:

Live On Wandbox(注意,显然无法成功运行,因为它不满足任何不变量(

#define BOOST_ALLOW_DEPRECATED_HEADERS
#include <boost/config.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/boykov_kolmogorov_max_flow.hpp>
#include <boost/graph/edmonds_karp_max_flow.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/push_relabel_max_flow.hpp>
#include <boost/property_map/function_property_map.hpp>
int main() {
struct VertexProperty final {};
// struct EdgeProperty final {};
using EdgeProperty = boost::property<boost::edge_capacity_t, int>;
using Graph =
boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
VertexProperty, EdgeProperty>;
using Edge = boost::graph_traits<Graph>::edge_descriptor;
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
auto g = Graph{};
auto s = Vertex{};
auto t = Vertex{};
auto residualCapacityMap = std::vector<int>{};
auto reverseEdgeMap = std::vector<Edge>{};
auto colorMap = std::vector<boost::default_color_type>{};
auto predcessorMap = std::vector<Edge>{};
auto distanceMap = std::vector<int>{};
auto vertex_index_map =
boost::make_function_property_map<Vertex>([](Vertex) { return 0; });
auto edge_index_map =
boost::make_function_property_map<Edge>([](Edge) { return 0; });
// auto capacity = boost::make_function_property_map<Edge>( [](Edge) { return 0; });
auto capacity = boost::get(boost::edge_capacity, g);
auto residual_capacity = boost::make_iterator_property_map(
residualCapacityMap.begin(), edge_index_map);
auto reverse_edge_map = boost::make_iterator_property_map(
reverseEdgeMap.begin(), edge_index_map);
auto color_map =
boost::make_iterator_property_map(colorMap.begin(), vertex_index_map);
auto predcessor_map = boost::make_iterator_property_map(
predcessorMap.begin(), vertex_index_map);
auto distance_map = boost::make_iterator_property_map(distanceMap.begin(),
vertex_index_map);
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);
boost::boykov_kolmogorov_max_flow(g, capacity, residual_capacity,
reverse_edge_map, vertex_index_map, s, t);
boost::boykov_kolmogorov_max_flow(g, s, t, props);
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);
}

正如您所看到的,所有的算法调用现在都在编译。

相关内容

最新更新