5

I've got a huge graph with typed edge (i.e. edge with a type property). Say

typedef adjacency_list<vecS, vecS, vertex_prop, edge_prop> Graph;  

The "type" of the edge is a member of edge_prop and has a value in {A,B,C,D},
I'd like to run the breadth first search algorithm considering only edges of type A or B.
How would you do that?

TylerH
  • 20,799
  • 66
  • 75
  • 101
log0
  • 10,489
  • 4
  • 28
  • 62

3 Answers3

11

Because it's hard to find simple example mixing different topics of the BGL, I post below a full and working example using filtered_graph and bundled properties.:

#include <iostream>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/filtered_graph.hpp>

using namespace boost;

enum edge_type_e {
  A, B, C, D
};

class edge_property_c {
public:
  edge_property_c(void) : type_m(A) {}
  edge_property_c(edge_type_e type) : type_m(type) {}
  edge_type_e type_m;
};

typedef adjacency_list<vecS, vecS, undirectedS, no_property, edge_property_c> graph_t;
typedef graph_t::edge_descriptor edge_id_t;

class edge_predicate_c {
public:
  edge_predicate_c() : graph_m(0) {}
  edge_predicate_c(graph_t& graph) : graph_m(&graph) {}
  bool operator()(const edge_id_t& edge_id) const {
    edge_type_e type = (*graph_m)[edge_id].type_m;
    return (type == A || type == B);
  }
private:
  graph_t* graph_m;
};

int main() {
  enum { a, b, c, d, e, n };
  const char* name = "abcde";
  graph_t g(n);
  add_edge(a, b, edge_property_c(A), g);
  add_edge(a, c, edge_property_c(C), g);
  add_edge(c, d, edge_property_c(A), g);
  add_edge(c, e, edge_property_c(B), g);
  add_edge(d, b, edge_property_c(D), g);
  add_edge(e, c, edge_property_c(B), g);

  filtered_graph<graph_t, edge_predicate_c> fg(g, edge_predicate_c(g));

  std::cout << "edge set: ";
  print_edges(g, name);
  std::cout << "filtered edge set: ";
  print_edges(fg, name);

  return 0;
}
toch
  • 3,905
  • 2
  • 25
  • 34
3

Finally I think the boost::graph way to do this is to use boost:filtered_graph and demo for usage

"The filtered_graph class template is an adaptor that creates a filtered view of a graph. The predicate function objects determine which edges and vertices of the original graph will show up in the filtered graph."

Thus, you can provide a edge (or vertex) filtering functor base on a property_map. In my case I'm using internal bundled properties. See Properties maps from bundled properties.

gongzhitaao
  • 6,566
  • 3
  • 36
  • 44
log0
  • 10,489
  • 4
  • 28
  • 62
0

I'm rather unfamiliar with boost::graph but I assume BFSVisitor is what you are looking for. It allows you to change the behaviour of the algorithm and your specific case would be to change the examination of outgoing edges after vertex discovery and to ignore the ones that are not of the required "type" (actually {A,B,C,D} are values as far as I understand and not types in the strict sense).

pmr
  • 58,701
  • 10
  • 113
  • 156
  • The event point you are referring to seems nice (vis.examine_edge(e, g)) But 1/ It comes in fact *after* getting the target vertex of the edge. (for_each edge {Vertex v = target(*ei, g); vis.examine_edge(*ei, g); ... }. 2/ The edge is given by copy so I don't really see how the algorithm above could ignore it. – log0 Apr 23 '10 at 09:26