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

if add_vertex in BGL checks for the existence of the vertex

在 BGL 中,add_edge 检查边缘是否已经存在。 add_vertex是否有相同的机制? 例如,如果我们有一个带有一些 bundled_properties 的顶点,然后我们将它添加到图中,然后将一条边连接到它,那么这个顶点 duplicated 如果有是相似的顶点吗?

When two vertices have similar properties (internal, or bundled) they are the same vertex, and add_vertex instead of adding it with new index shouldn't just return the index to an existing one? –

如果您有两个具有 "similar properties" 的顶点, 决定是否要添加具有这些属性的另一个顶点。

if we have a vertex with some bundled_properties, and then we add it to the graph, and then connect an edge to it, would be this vertex duplicated if there was a similar vertex?

你通过参考vertex_descriptor来添加边。没办法"connect an edge to vertex properties"。因此,add_edge 不会意外地使用一些 属性.

创建新的顶点

Note: There might be confusion because using vectorS² for vertex container selector lets you add edges by referring to potentially non-existing vertex descriptors. Really, that doesn't "add vertices" as much as it "extends the valid domain for vertex ids/descriptors". E.g.:

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

doesn't really add 12 vertices. It extends the vertex id domain to encompass the value 11. Live 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;

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

The important point here is that adjacency_list does not know or care about the properties. They add information for you, or useful for certain algorithms, but they are not relevant to the graph concept modeled by adjacency_list.

为什么add_edge有条件添加?

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

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

总结:

  • add_vertex does not take any identifying information, hence it doesn't need to check for constraints (in fact, it cannot).

  • add_edge does take identifying information (the endpoint vertices) and it can check these against the constraints that arise from the strategies that you chose when instantiating the adjacency_list.


¹ 例如优雅地避免双边

² 或其他可能的随机访问顶点容器选择器,它们具有作为 implicit 顶点 id

的完整顶点描述符