4

I'm new in using C++ boost library in particularly the boost graph library which a needed to try coding some algorithms where i commonly check the adjacency of two vertices and dealing with other graph concepts like computing graph invariants. What i know is that we can iterate through adjacent vertices with the function : adjacent_vertices(u, g) but i'm searching for an efficient way to test if two vertices u, v are adjacent or not without doing linear search

user9879283
  • 99
  • 4
  • 9

2 Answers2

9

The AdjacencyMatrix concept gives a complexity guarantee that the edge() function must return in constant time.

To check if two vertices v and w are adjacent in G, you write edge(v, w, G).second, since the function returns a pair where the second value indicates if the edge exists.

The edge() function is implemented for other graph representations as well. Here is a graph that shows how different representations compare with regard to performance of checking vertex adjacency:

Adjacency check efficiency

Here is the code used to generate the data for this plot. Each data point is 100 random graphs of medium density, with 100 random edge checks per each graph. Note the logarithmic y axis.

What is the best choice will eventually depend on your particular application, because for other operations the ordering of structures by speed is different. In other words, avoid premature optimization.

arekolek
  • 9,128
  • 3
  • 58
  • 79
  • Loving the graph. Thanks for sharing the code. What did you use to make the graph from the raw data? – sehe Apr 29 '16 at 07:34
  • @sehe I used [`R`](https://www.r-project.org/) to compute mean and standard deviation of data points, using `ddply` from the `plyr` package. The graph was made with [`gnuplot`](http://www.gnuplot.info/) and the [ColorBrewer](https://github.com/aschn/gnuplot-colorbrewer) color scheme. – arekolek Apr 29 '16 at 11:16
  • @sehe Here are the [files](https://gist.github.com/arekolek/e855cc8740a8782f48d5/fe7d86e8dcc5775c686518f816b050212a146b13). This version compares other operations in addition to `edge()`, the old version got overwritten. Bear in mind, I wasn't going for readability in the `gnuplot` and `R` files. – arekolek Apr 29 '16 at 11:35
2

BGL is a highly generic library. You can adapt most any datastructure for use with its algorithms.

You can vary the edge container. You don't mention it, but I'm assuming you've been looking at the interface/complexity guarantees for boost::adjacency_list.

Indeed the edge membership test will be O(n) even if you use setS for the edge container selector. This is mostly because adjacency lists store outgoing edges are per vertex. So in worst case, each vertex contains at most one outgoing edge and the search is practically O(n) [1]

In this case you simply want to select another graph implementation.

The documentation page on Graph Concepts is a good starting point to find out about which concepts are expected. As well as, which models supply those concepts.

In the worst case you can adapt your data structure for use with Boost Graph algorithms. E.g. you could store all edges in a simple std::[unordered_]set<std::pair<VID, VID> > and adapt it to model the EdgeListGraph concept.

That way you will have performant lookups.


[1] of course this also means, in best case the search is whatever your set implementation affords: O(log n) because all edges could originate from the same vertex...

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Effectively the use of an unordered_set to store edges can bring me fast lookup, but i didn't understand what you mean by `adapt it to model the EdgeListGraph concept`, i'm very novice in generic programing. – user9879283 Mar 11 '15 at 20:09
  • Yeah. well. The documentation has examples, you may be able to find some on SO. I find it a bit unwarranted to start fantasizing about a graph model before you show me what your starting position even is :) – sehe Mar 11 '15 at 20:24
  • i found that [here](http://www.boost.org/doc/libs/1_57_0/libs/graph/doc/using_adjacency_list.html#sec:choosing-graph-type) we can choose `hash_setS` which is an unordered_map as underlying containerfor edge list, and found the function `edge(u, v, g)` retruns `pair` where the bool is whether the edge exists, but i dont know how the choice of `hash_setS` can affect this operation – user9879283 Mar 11 '15 at 20:57
  • That's detailed in my answer. Recap: not useful unless all your edges originate from very few vertices (still O(num_source_vertices)) – sehe Mar 11 '15 at 20:59
  • okey, so hash_setS selector didn't help much, i presume that i need a custom data structure to bring the fast look up and instant neighboring, but adapt this with BGL requires to me more deeper understanding of the library concepts that I do not yet grasped as a beginner. – user9879283 Mar 11 '15 at 21:26
  • the doc is very intimidating to me, i juste know the two basics djacency_list and adjacency_matrix. – user9879283 Mar 11 '15 at 21:38
  • A traditional adjacency matrix should give you constant time adjacency testing, but I'm not sure how to get at that functionality through boost's adjacency_matrix. – pbible Mar 12 '15 at 16:50