【问题标题】:When analyzing boost::graph, does one operate on vertex and edge descriptor or their iterators?在分析 boost::graph 时,是否对顶点和边描述符或其迭代器进行操作?
【发布时间】:2017-10-12 06:46:43
【问题描述】:

在使用 BOOST 图形库时,我有一个完全初始化的图形实例——结构现在是静态的。我需要根据图表做一些处理。

我不清楚我应该使用顶点和边的迭代器类型,还是顶点和边类型本身?

typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, VertexProperty, EdgeProperty > GraphType;

typedef typename boost::graph_traits< GraphType >::vertex_descriptor VertexType;
typedef typename boost::graph_traits<GraphType>::vertex_iterator VertexIterator;

typedef typename boost::graph_traits< GraphType >::edge_descriptor   EdgeType;
typedef typename boost::graph_traits<GraphType>::out_edge_iterator EdgeIterator;

我有一个算法,我需要检查两条边是否“相同”。 (在最强烈的意义上。假设该图有两条平行边连接 E1(S1,T2) 和 E2(S1,T2)。一条边最多只能与其中一条“相同”。

(edge_descriptor == edge_descriptor) 和 (edge_iterator == edge_iterator) 之间有什么区别?关于顶点的相同问题。

大多数图函数返回迭代器而不是边/顶点类型本身。

我还需要存储一组边。 不确定我应该存储 EdgeType 还是EdgeIterator?

std::vector<EdgeType>  processedEdges;
std::vector<EdgeIterator>  processedEdges;

vit = std::find( processedEdges.begin(), processedEdges.end(), anotherEdgeRef )
if ( vit == processedEdges.end() )
    doSomethingBasedOnEdgeProperty(*vit);

参考: http://www.boost.org/doc/libs/1_64_0/libs/graph/doc/adjacency_list.html

【问题讨论】:

  • 如果我将迭代器类型一般视为“指向知道如何迭代的实例的指针”,那么似乎很自然的事情就是使用(例如 operator==)并存储迭代器。显然,如果图结构发生变化,它们可能无效,所有迭​​代器必须针对同一个图实例。

标签: c++ boost graph iterator


【解决方案1】:

您应该存储描述符,而不是迭代器。

迭代器与逻辑范围相关,而不是图表。迭代器可能在同一张图的不同范围之间无效:

auto range1 = out_edges(vertex1, g);
auto range2 = out_edges(vertex2, g);

assert(range1.first != range2.first); // unspecified or undefined

相反,描述符是图范围的。根据图模型,描述符可能更稳定:如果操作使迭代器无效,则不一定会使与相同图元素对应的描述符无效。

换句话说,这使得描述符更适合用作顶点或边“ID” - 或者,正如 Boost Graph 所称的那样,vertex_index 或 edge_index 属性。

我认为这与您的问题非常接近。

一个警告:即便如此,描述符可能并不总是稳定的!

例如:

adjacency_list<vecS, vecS, directedS>

导致顶点描述符在追加时稳定,但在追加时不稳定 删除。

adjacency_list<setS, listS, directedS>

另一方面,导致顶点描述符在两者上都是稳定的 插入和删除。

参见文档部分"Iterator and Descriptor Stability/Invalidation"

如果您需要一个完全稳定的图形元素标识,您可能需要添加一个作为(捆绑的)属性。

【讨论】:

  • “迭代器与逻辑范围相关,而不是图表。”这很令人信服。我最初对存储描述符的担忧是不确定描述符的实际重量。我想知道我是否将它们存储在一个容器中,我是否还存储了相关属性的副本?这更像是一个实施问题。我主要是想解决概念上的差异,您对此有所帮助。 :-) 我认为在这种情况下我不需要担心稳定性,因为我知道图形结构在代码执行此处理时是固定的。
  • 描述符设计得很轻。因为它们是整数(实际上是整数或 void*)。
猜你喜欢
  • 1970-01-01
  • 2018-08-07
  • 2016-04-07
  • 1970-01-01
  • 1970-01-01
  • 2011-12-08
  • 2021-09-14
  • 2012-08-14
  • 1970-01-01
相关资源
最近更新 更多