1

There aren't too many examples for graphs that do strongly connected components on listS rather than vecS. Here is an equivalent example for vecS

#include <boost/config.hpp>
#include <vector>
#include <iostream>
#include <boost/graph/strong_components.hpp>
#include <boost/graph/adjacency_list.hpp>

int
main()
{
  using namespace boost;
  typedef adjacency_list < vecS, vecS, directedS > Graph;
  const int N = 6;
  Graph G(N);
  add_edge(0, 1, G);
  add_edge(1, 1, G);
  add_edge(1, 3, G);
  add_edge(1, 4, G);
  add_edge(3, 4, G);
  add_edge(3, 0, G);
  add_edge(4, 3, G);
  add_edge(5, 2, G);

  std::vector<int> c(N);

  int num = strong_components
    (G, make_iterator_property_map(c.begin(), get(vertex_index, G), c[0]));

    auto l=get(vertex_index, G);

  std::cout << "Total number of components: " << num << std::endl;
  std::vector < int >::iterator i;
  for (i = c.begin(); i != c.end(); ++i)
    std::cout << "Vertex " << i - c.begin()
      << " is in component " << *i << std::endl;
  return EXIT_SUCCESS;
}

But when I change from vecS to listS, it breaks. I know the problem is because of sometype of mismatch in the vertex index and the output vector index but I couldn't exactly come up with a way to solve it. The closest answer is Which VertexList types are valid for depth_first_search but this is for DFS and cannot extrapolate to SCC.

AsyncLad
  • 15
  • 4

1 Answers1

0

There aren't too many examples for graphs that do strongly connected components on listS rather than vecS. Here is an equivalent example for vecS

"There isn't much information for playing board games when underwater rather than on land"

The reason is that there's nothing specific to the algorithm you mention (connected components). The problem you're facing is that using listS loses the implicit vertex_index property. This breaks everything that requires it.

Specifically, you would notice that the add_edge call already fails to compile.

You need to add a vertex index. Much like doing any activity underwater requires a solution for oxygen management.

So look for examples for that e.g. here.

In fact... I immediately ran into a duplicate question that I answered in 2017:

Find connected components using Boost Graph library, with the vertex and edge type being boost::listS

Simplest Change:

Simplest change to your sample code:

Live On Coliru

#include <boost/config.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/strong_components.hpp>
#include <iostream>
#include <vector>
using boost::make_iterator_range;

int main() {
    typedef boost::adjacency_list<boost::vecS, boost::listS, boost::directedS,
            boost::property<boost::vertex_index_t, int>
        > Graph;

    Graph G(6);
    auto idmap = get(boost::vertex_index, G);
    {
        // initialize idmap
        int id = 0;
        for (auto& v : make_iterator_range(vertices(G)))
            idmap[v] = id++;
    }

    auto add_edge = [&](int i, int j) {
        return boost::add_edge(vertex(i, G), vertex(j, G), G);
    };

    add_edge(0, 1);
    add_edge(1, 1);
    add_edge(1, 3);
    add_edge(1, 4);
    add_edge(3, 4);
    add_edge(3, 0);
    add_edge(4, 3);
    add_edge(5, 2);

    std::vector<int> c(num_vertices(G));

    int num = strong_components(
        G, make_iterator_property_map(c.begin(), idmap, c[0]));

    //auto l = get(vertex_index, G);

    std::cout << "Total number of components: " << num << std::endl;
    std::vector<int>::iterator i;
    for (i = c.begin(); i != c.end(); ++i)
        std::cout << "Vertex " << i - c.begin() << " is in component " << *i
                  << std::endl;
}

Prints

Total number of components: 3
Vertex 0 is in component 0
Vertex 1 is in component 0
Vertex 2 is in component 1
Vertex 3 is in component 0
Vertex 4 is in component 0
Vertex 5 is in component 2
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Added a [live demo](http://coliru.stacked-crooked.com/a/e56c3de1cc99ec3d) of a simple edit to make the example work with `listS` – sehe May 08 '20 at 12:50
  • It works like a charm! Much appreciated. I was getting around to this solution but got stuck at creating the right property map. Thanks a lot. – AsyncLad May 08 '20 at 13:42
  • I notice that you mentioned it is like playing board games underwater. Do you think there is a better way of doing this? My end objective is to run SCC on node IDs that aren't continues(it can have gaps) so I thought listS would be better suited for that. – AsyncLad May 08 '20 at 13:59
  • I meant that as a playful comparison only because doing any activity under water requires largely the same preparation regardless of the activity. It wasn't meant to imply this was doing it the wrong way (there are legitimate reasons to e.g. sport or weld under water; perhaps board games was a bad example to go with :)) – sehe May 08 '20 at 14:19
  • On the subject of non-contiguous IDs, I would say that is [orthogonal](https://en.wikipedia.org/wiki/Orthogonality_(programming)) to the choice of data-structure. Although it is often convenient to use the default `vertex_index`, there certainly is no "law" that says you must: http://coliru.stacked-crooked.com/a/9458e75d2e6ce1b3 – sehe May 08 '20 at 14:34