4

I am trying to use the Boost Ggraph Library. On each iteration of my program, I have a set of points, e.g. {1,2,3,4,5,6,7,8,9,10} on iteration one and {1,2,3,...,1000} on iteration two, ...

For each point I know which other points it is connected to, e.g. at iteration one every point is connected as below:

c(1)={3,5,7,8}   
c(2)={}   
c(3)={1,4,10}   
c(4)={3}    
c(5)={1,9}   
c(6)={}    
c(7)={1,8}    
c(8)={1,7}    
c(9)={5}    
c(10)={3}    

Each point has a property, e.g. p(1)=10, p(2)=100, p(3)=20, ...

How can I create an undirected graph in Boost and iterate over the connected component(s)?

Agostino
  • 2,723
  • 9
  • 48
  • 65
ziv
  • 189
  • 1
  • 9

1 Answers1

12

You will need to include the following headers:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>

Then you need to declare a type for your graph. The following is suitable for the requirements you gave, however you might want to consult this page to learn more about other choices for template parameters:

typedef
  boost::adjacency_list<
    boost::vecS            // edge list
  , boost::vecS            // vertex list
  , boost::undirectedS     // directedness
  , float                  // property associated with vertices
  >
Graph;

You may create a graph with a given number of points, and you may later add more points:

Graph c (10);              // create a graph with 10 points
boost::add_vertex (c);     // add a vertex to the graph

To add edges use (note that vertices are enumerated starting from 0):

boost::add_edge (0, 1, c); // add an edge between vertices 0 and 1 in the graph

Finally, with the following piece of code you may compute connected components in your graph:

std::vector<int> component (boost::num_vertices (c));
size_t num_components = boost::connected_components (c, &component[0]);

The value returned from the function is the number of found components. Each item in component vector will be set to the component id of the corresponding vertex. This means that you can iterate over it and e.g. print the vertices that belong to a particular component:

std::cout << "Vertices in the first component:" << std::endl;
for (size_t i = 0; i < boost::num_vertices (c); ++i)
  if (component[i] == 0)
    std::cout << i << " ";
taketwo
  • 1,211
  • 9
  • 10
  • Thanks @taketwo. In case, I would have several sub-graphs in this collection, does boost also give me number of available sub-graphs? can I iterate through my sub-graphs with this. – ziv Mar 30 '14 at 16:47
  • Yes, boost returns the number of components found (as one might expect, it is stored in `num_components` in the second last snippet). Also, the very last snippet shows how to iterate though vertices of a particular component (i.e. subgraph). You may add another loop around it to iterate though all components. Another option is to look at [boost-subgraph](http://www.boost.org/doc/libs/1_55_0/libs/graph/doc/subgraph.html). BTW, if your original question is answered, please accept the answer. – taketwo Mar 30 '14 at 18:43
  • This is not correct, for example if vertex with vertex descriptor 0 was deleted from the graph, the graph consists of vertex descriptors 1, 2, ..., boost::num_vertices(c). You need to keep track of the vertex descriptors of these vertices, it is not safe to assume that vertex descriptors at any given time are simply 0 -> num_vertices()-1. – j x Sep 10 '18 at 20:27
  • I suppose what you mean is that `std::cout << i << " ";` does not give us vertex descriptors, but rather sequential indices into the vector of vertices of the graph? Please suggest a fix, I will be happy to update the last snippet. – taketwo Sep 11 '18 at 21:31