4

I have a directed multigraph with vertices A..C and edges E1..E4

A ---E1--> B
A ---E2--> B
A ---E3--> B
B ---E4--> C

I wanted to iterate over the edges that connect A and B.

In BGL, I expressed this as:

#include <boost/graph/adjacency_list.hpp>

struct Vertex
{
  std::string code;
};

struct Edge
{
  double distance;
  std::string code;
};

int main()
{
  using namespace boost;
  typedef adjacency_list<listS, vecS, directedS, Vertex, Edge> Graph;
  Graph g;
  auto a= add_vertex(Vertex{ "A" }, g);
  auto b= add_vertex(Vertex{ "B" }, g);
  auto c= add_vertex(Vertex{ "C" }, g);
  add_edge(a, b, Edge{ 10, "E1" }, g);
  add_edge(a, b, Edge{ 10, "E2" }, g);
  add_edge(a, b, Edge{ 10, "E3" }, g);
  add_edge(a, c, Edge{ 10, "E4" }, g);

  // checking number of edges
  std::cout<< num_edges(g)<< std::endl;

  // printing edges branching from A
  auto erange= out_edges(a, g);
  for(auto i= erange.first; i!= erange.second; ++ i)
    std::cout<< g[*i].code<< std::endl;

  // now we want to iterate over edges that connect A and B
  auto wtf= boost::edge_range(a, b, g);
}

Which results in a compilation error:

In file included from /usr/include/boost/graph/adjacency_list.hpp:246:
/usr/include/boost/graph/detail/adjacency_list.hpp:1617:25: error: no matching constructor for initialization of 'StoredEdge' (aka
      'boost::detail::stored_edge_property<unsigned long, Edge>')
        equal_range(el, StoredEdge(v, fake_edge_container.end(),
                    ^          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I've read the documentation:

std::pair<out_edge_iterator, out_edge_iterator> edge_range(vertex_descriptor u, vertex_descriptor v, const adjacency_list& g) Returns a pair of out-edge iterators that give the range for all the parallel edges from u to v. This function only works when the OutEdgeList for the adjacency_list is a container that sorts the out edges according to target vertex, and allows for parallel edges. The multisetS selector chooses such a container.

( http://www.boost.org/doc/libs/1_54_0/libs/graph/doc/adjacency_list.html )

Modified the graph:

typedef adjacency_list<multisetS, vecS, directedS, Vertex, Edge> Graph;

But the error did not change.

So how do you list edges between two vertices (from-> to) in a directed multigraph using BGL ?

I found a quick and dirty way:

auto erange= out_edges(a, g);$
for(auto i= erange.first; i!= erange.second; ++ i)$
  std::cout<< g[*i].code<< " -> "<< g[target(*i, g)].code<< std::endl;$

Which will let me filter edge by target vertex. But how do you use boost::edge_range ?

nurettin
  • 11,090
  • 5
  • 65
  • 85

1 Answers1

1

This bug has been reported before on the Boost mailinglist.

it fails to compile when the Directed Selector template argument to adjacency_list is set to directedS, but does work if the argument is either undirectedS, or bidirectionalS. Attached below is a short program illustrating the problem. The problem is that edge_range() instantiates a StoredEdge via a constructor taking 3 arguments, but when the Directed Selector is directedS StoredEdge is typedef'ed to stored_edge_property, which has no such constructor. One solution might be to create overloaded edge_range_dispatch() functions, and dispatch on
Config::on_edge_storage.

Changing directedS to undirectedS in your program works. Live Example. But that might not be what you need for your application, so the simple filter you mentioned before might be better. You could repost this on the Boost mailinglist to get more attention for it.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • I tried an undirected graph. Outcome was very entertaining within the context of my application. – nurettin Oct 07 '13 at 13:46
  • that's too bad, I can understand the annoyance. You should definitely trie to contact the library's author or the Boost mailinglist. This might be succesful if you also tried to implement the suggestion of a separate `_dispatch()` overload and submitted that a bug fix. – TemplateRex Oct 07 '13 at 13:47
  • 2
    That should now be fixed in the Boost trunk as of r86469. Sending bug reports to the boost-users mailing list or filing them at https://svn.boost.org/trac/boost would speed up getting fixes to this kind of problem in the future. – Jeremiah Willcock Oct 26 '13 at 22:57
  • @JeremiahWillcock tnx, much appreciated! – TemplateRex Oct 26 '13 at 22:59