为什么使用vecS作为OutEdgeList模板参数的boost adjacency_list会使遍历的边无效?

问题描述

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

引用第一个链接

下表总结了哪些操作导致描述符和迭代器无效。在表中,EL是OutEdgeList的缩写,而VL表示VertexList。 “调整迭代器”类别包括out_edge_iterator,in_edge_iterator和adjacency_iterator类型。
文档中针对每个操作对描述符和迭代器无效进行了更详细的描述。

Table: Summary of Descriptor and Iterator Invalidation

我了解到,如果对vecS使用VertexList,则remove_vertex()上的所有顶点描述符都将被调整为仍然连续。

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

我是否正确理解该表,因为它说:“如果对vecS的{​​{1}}图上的边缘列表类型使用adjacency_list,那么您将无法稳定地进行迭代边缘,因为对其进行迭代将使边缘迭代器和边缘描述符无效?

如果我确实正确理解了这一点,请解释为什么会这样。如果我误会了,请对边缘列表使用directedS来说明实际效果
谢谢。

解决方法

您怀疑它是在误读。

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

仅凭迭代就不会改变adjacency_list,因此不能使描述符或迭代器无效。

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

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

提示

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