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
?
This bug has been reported before on the Boost mailinglist.
Changing
directedS
toundirectedS
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.