问题描述
我正在尝试解决在有向图中找到树状结构的问题。此功能由 boost 图库 not provided directly 提供。但是,可以使用基于 boost 图库的实现here。
void
edmonds_optimum_branching(TEdgeListGraph &g,TVertexIndexMap index,TWeightMap weight,TInputIterator roots_begin,TInputIterator roots_end,TOutputIterator out);
作者对roots_begin
和roots_end
的描述是:
roots_begin 和 roots_end 是 g 顶点上的迭代器。任何 这个范围内的顶点保证是最终的根 分枝。这个范围当然可能是空的,在这种情况下 算法找到合适的根。
edmonds_optimum_branching<true,false,false>(G,vertex_indices,weights,static_cast<Vertex *>(0),//Is this conversion to an empty iterator ?
static_cast<Vertex *>(0),// or is this conversion to an iterator pointing to vertex 0,the first node?
std::back_inserter(branching));
如果我理解正确,roots_begin
和 roots_end
都是 NULL (?),因此问题在没有预先指定的根源的情况下解决了。
假设我有一个有 50 个顶点的图,并且我希望顶点 5 作为根节点,会发生什么变化?
这两个参数应该是:
edmonds_optimum_branching<true,static_cast<Vertex *>(5),static_cast<Vertex *>(6)
std::back_inserter(branching));
然而,这将 static_cast
上的编译时错误显示为 int 的无效类型转换。
这两个参数应该是:
edmonds_optimum_branching<true,5,6,std::back_inserter(branching));
然而,这也不会编译错误:
../include/edmonds_optimum_branching_impl.hpp:247:41: error: invalid type argument of unary ‘*’ (have ‘int’)
247 | is_specified_root[index[*roots_begin]] = true;
我也在作者的github页面上发了这个问题,但是作者好像不常访问。
解决方法
迭代器是指针的泛化。指针是迭代器,但更复杂的东西,比如 std::vector<T>::begin
和 std::vector<T>::return
返回以及 std::back_inserter
结构也是迭代器。您似乎缺少的关于它们的关键是,如果 it
是一个迭代器,那么与其关联的值将作为 *it
而不是 it
访问。因为您不能取消引用 int
,所以它不是一个有效的迭代器。
您需要完全按照文档说明进行操作:提供定义包含 5
的范围的迭代器。因为指针是迭代器,你可以这样做
int root = 5;
edmonds_optimum_branching<true,false,false>(
G,vertex_indices,weights,&root,&root + 1,// *&root = 5,std::next(&root) = &root + 1,so this range produces 5 and then ends
std::back_inserter(branching))
该示例使用指针是迭代器来传递 nullptr
和 nullptr
作为定义空范围的事实。在类型上,nullptr
是一个指针,因此 *it
中 edmonds_optimum_branching
的所有使用都可以编译,但是在实际执行开始和结束迭代器时会发现它们相等,因此不会进行访问.