如果BGL中的add_vertex检查是否存在顶点

时间:2017-08-16 12:34:06

标签: c++ boost boost-graph

在BGL中,add_edge检查边缘是否已存在。 add_vertex是否有相同的机制? 例如,如果我们有一个带有bundled_properties的顶点,然后我们将它添加到图形中,然后将边连接到它,如果有类似的话,这个顶点重复顶点?

1 个答案:

答案 0 :(得分:2)

  

当两个顶点具有相似的属性(内部或捆绑)时,它们是相同的顶点,而add_vertex而不是用新索引添加它不应该只将索引返回到现有的顶点吗? - Bruce 11 mins ago

如果您有两个具有“相似属性”的顶点,决定是否要添加具有这些属性的另一个顶点。

  

如果我们有一个带有一些bundled_properties的顶点,然后我们将它添加到图形中,然后将一条边连接到它,如果有一个类似的顶点,这个顶点会重复吗?

您可以通过引用vertex_descriptor来添加边缘。没有办法“将边连接到顶点属性”。因此,add_edge不能使用某些属性意外创建新的顶点。

  

注意:可能会出现混淆,因为对顶点容器选择器使用vectorS²可以通过引用可能不存在的顶点描述符来添加边。实际上,它不像“扩展顶点id /描述符的有效域”那样“添加顶点”。 E.g:

adjacency_list<> g;
add_edge(10, 11, g);
     

并没有真正添加12个顶点。它扩展顶点id域以包含值11Live On Coliru

让我们看一下add_vertex

调用是add_vertex并且它添加了一个顶点。实际上,您通常不会为它们插入属性,这只是一种便利。

之间没有根本区别:

vertex_descriptor v = add_vertex(g);

g[v] = vertexProperties;

并且

vertex_descriptor v = add_vertex(vertexProperties, g);

在这两种情况下,您将始终获取一个新的,唯一的顶点描述符,并将其属性设置为特定值。

为什么与add_edge的区别呢?

add_edge真的不同吗?与add_vertex一样,之间没有区别:

vertex_descriptor from {/*...*/}, to {/*...*/};
edge_descriptor e = add_edge(from, to, g).first;

g[e] = edgeProperties;

并且

edge_descriptor e = add_edge(from, to, edgeProperties, g).first;

你会注意到两个(可能)添加一个边,返回它的描述符,并且都将属性设置为特定的值。

  

重点是adjacency_list 知道或关心这些属性。它们为您添加信息,或对某些算法有用,但它们 adjacency_list建模的图形概念无关。

为什么add_edge 有条件地添加?

那是因为adjacency_list使用了暗示需要检查的不变量的策略:

  • 如果您的边缘容器选择恰好是例如setS,其插入方法可能会也可能不会插入新边缘; adjacency_lists<>只是将行为¹转发给add_edge
  • 如果您的adjacency_list也使用undirectedbidirectional,则会对边缘产生额外的限制(例如,阻止添加(a->b)以及(b->a)使用setS作为边缘容器选择器的双向图。

汇总:

  
      
  • add_vertex 获取任何识别信息,因此不需要检查约束(事实上,它不能)。

  •   
  • add_edge 获取识别信息(端点顶点),它可以根据您在实例化{{1}时选择的策略所产生的约束来检查这些信息}。

  •   

¹,例如优雅地避免加倍边缘

²或可能是其他随机访问顶点容器选择器,它们具有作为隐式顶点id的整数顶点描述符