【问题标题】:Why does a boost adjacency_list using vecS as OutEdgeList template parameter invalidate edges on traversal?为什么使用 vecS 作为 OutEdgeList 模板参数的 boost adjacency_list 在遍历时会使边无效?
【发布时间】:2021-02-07 07:37:42
【问题描述】:

我正在阅读有关 adjacency_list 的文档以及 choosing the graph type 对内存消耗、big-O 运行时和描述符稳定性的影响。

引用第一个链接:

下表总结了哪些操作导致描述符和迭代器无效。表中EL是OutEdgeList的缩写,VL是VertexList的缩写。 Adj Iter 类别包括 out_edge_iterator、in_edge_iterator 和 adjacency_iterator 类型。
每个操作的文档中给出了描述符和迭代器失效的更详细描述。

我知道,如果将vecS 用于VertexList,那么remove_vertex() 上的所有顶点描述符都将被调整,以便它们仍然是连续的。

我不明白为什么显然使用vecS 会导致边缘迭代使边缘描述符无效。

我是否正确理解该表,因为它说“如果您在 adjacency_list 图形上使用 vecS 边缘列表类型,即 directedS,那么您无法稳定地迭代边缘,因为迭代它们将使边缘迭代器和边缘描述符无效”?

如果我理解正确,请解释为什么会这样。如果我理解错了,请澄清使用vecS为Edge List的实际效果。
谢谢。

【问题讨论】:

    标签: c++ boost boost-graph adjacency-list


    【解决方案1】:

    正如您所怀疑的那样,您误读了它。

    混淆是“Edge Iter”、“Vertex Iter”和“Adj Iter”列是“Iterator”的缩写,而不是“iteration”。

    单纯的迭代行为永远不会改变adjacency_list,因此不能使描述符和迭代器无效。

    有些图模型的描述符比迭代器(迭代器)更稳定。这实际上是描述符概念的关键原因。任何具有引用稳定性的容器选择器(即基于节点的容器)自然会具有迭代器稳定性(仅使擦除节点的迭代器无效)。

    该表很有用,因为对于“不可变”(或很少更改,经常查询)图的性能,可以通过选择连续存储(如 vecS)大大增强,并且它们自然会施加更多限制性的无效规则(例如向量可能重新分配,这使所有迭代器无效,但描述符可能会保持稳定直到修改/插入的索引)。

    提示

    要对基本的失效问题进行原始编译时检查,请考虑通过 const 引用来获取您的图表。这将消除意外修改的可能性。当然,在某些情况下,您确实想在想要对图形执行修改的地方(为了性能)走到边缘,并且您必须仔细阅读文档以确切了解哪些无效规则适用于该修改。

    【讨论】:

    • 啊,所以表格说例如如果我们在directedS adjacency_list 上使用vecS 作为 Edge List 类型,那么描述符仍然有效,但当我们删除一条边时迭代器无效。这更有意义,谢谢!
    • 为了确保我做对了:根据表格,如果我使用 Edge List 类型 listS 并遍历某个顶点的 outEdges,则在该迭代期间删除或添加一条边不会中断迭代器。对吗?
    猜你喜欢
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 2019-08-17
    相关资源
    最近更新 更多