graph-theoryboost-graphcomplex-networks

Boost Graph Library: checking whether a graph is directed or not


I am writing a function that performs some calculation on graphs using the BGL. The way the calculation is done depends on whether the graph is directed or not, but I would like to avoid writing two different functions, one for undirected graphs and one for directed graphs. Both types of graph are defined as follows

using namespace boost;
// Undirected
typedef adjacency_list<listS, vecS, undirectedS> UGraph;
// Directed
typedef adjacency_list<listS, vecS, bidirectionalS> DGraph;

Is there a way to check whether a graph is directed or not from the graph object itself? In other words, is there a way to know, from the graph object, the "directedness" property used (i.e., undirectedS, bidiretionalS or directedS)?


Solution

  • I found the answer while looking at the definition of the function print_graph() in graph_utility.hpp, which led me to the function is_directed() defined in graph_traits.hpp.

    I suppose there may be a more elegant way to do this, but here is a minimal working example:

    #include <iostream>
    #include <boost/graph/adjacency_list.hpp>
    #include <boost/graph/graph_traits.hpp>
    
    
    template <typename graph_t>
    void print_directedness(graph_t &g)
    {
      // Typedef of an object whose constructor returns "directedness" of the graph object.
      typedef typename boost::graph_traits<graph_t>::directed_category Cat;
      // The function boost::detail::is_directed() returns "true" if the graph object is directed.
      if(boost::detail::is_directed(Cat()))
        std::cout << "The graph is directed." << std::endl;
      else
        std::cout << "The graph is undirected." << std::endl;
    }
    
    
    int main()
    {
    
      // Creates an undirected graph and tests whether it is directed of not.
      boost::adjacency_list< boost::setS, boost::vecS, boost::undirectedS > UnGraph;
      print_directedness(UnGraph);
    
      // Creates a directed graph and tests whether it is directed of not.
      boost::adjacency_list< boost::setS, boost::vecS, boost::directedS > DiGraph;
      print_directedness(DiGraph);
    
      // Creates a bidirectional graph and tests whether it is directed of not.
      boost::adjacency_list< boost::setS, boost::vecS, boost::bidirectionalS > BidiGraph;
      print_directedness(BidiGraph);
    
      return 0;
    }
    

    which correctly returns

    >> g++ minimal_working_example.cpp -o minimal_working_example
    >> ./minimal_working_example
    The graph is undirected.
    The graph is directed.
    The graph is directed.