if add_vertex in BGL checks for the existence of the vertex

99封情书 提交于 2019-12-11 08:43:05

问题


In BGL, add_edge checks if the edge already exists. Is there the same mechanism for add_vertex? For example, 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?


回答1:


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? – Bruce 11 mins ago

If you have two vertices with "similar properties", you decide whether you want to add another vertex with those properties or not.

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?

You add edges by referring to vertex_descriptors. There is no way to "connect an edge to vertex properties". So, add_edge cannot accidentally create a new vertex using some property.

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

Let's look at add_vertex:

The call is add_vertex and it adds a vertex. In fact, you don't usually insert properties for them, that's merely a convenience.

There is no fundamental difference between:

vertex_descriptor v = add_vertex(g);

g[v] = vertexProperties;

And

vertex_descriptor v = add_vertex(vertexProperties, g);

In both cases you will always get a new, unique, vertex descriptor, and have its properties set to a specific value.

Why the difference with add_edge then?

Is add_edge really different? Like with add_vertex there is no difference between:

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

g[e] = edgeProperties;

And

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

You will note that both (possibly) add an edge, returning its descriptor, and both set the properties to specific values.

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.

Why does add_edge conditionally add?

That's because the adjacency_list uses strategies that imply invariants that need to be checked:

  • if your edge-container selection happens to be e.g. setS, its insertion method may or may not insert a new edge; adjacency_lists<> just forwards the behaviour¹ to add_edge
  • if your adjacency_list uses undirected or bidirectional as well, this puts extra contraints on edges (e.g. preventing addition of (a->b) as well as (b->a) in a bidirectional graph that uses setS as the edge container selector).

Summarizing:

  • 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.


¹ e.g. to elegantly avoid doubled edges

² or possibly other Random Access vertex container selectors, that have integral vertex descriptors that act as implicit vertex id



来源:https://stackoverflow.com/questions/45713682/if-add-vertex-in-bgl-checks-for-the-existence-of-the-vertex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!