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?
- 415
- 2
- 19
-
how do you define "similar vertex". If you add a vertex, you get a new vertex by definition. If you want to keep indices by some other key, they're outside your graph. – sehe Aug 16 '17 at 17:00
-
You might be interested in the labeled graph adaptor, though https://stackoverflow.com/q/43114533/85371 – sehe Aug 16 '17 at 17:01
-
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? I am aware of `labeled_graph`, and I've already upvoted that question. – Bruce Aug 17 '17 at 12:07
1 Answers
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_listdoes 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 byadjacency_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¹ toadd_edge - if your
adjacency_listusesundirectedorbidirectionalas well, this puts extra contraints on edges (e.g. preventing addition of(a->b)as well as(b->a)in a bidirectional graph that usessetSas the edge container selector).
Summarizing:
add_vertexdoes not take any identifying information, hence it doesn't need to check for constraints (in fact, it cannot).
add_edgedoes take identifying information (the endpoint vertices) and it can check these against the constraints that arise from the strategies that you chose when instantiating theadjacency_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
- 374,641
- 47
- 450
- 633