23

If I have n elements defined with class CElement, how can one create vertices of those elements with boost graph - and connect them also? I've seen boost graph bundled props, but I just can't figure this one out.

dodol
  • 1,073
  • 2
  • 16
  • 33
  • sorry for not being clear. Instances of CElements are vertices. I'd like to be able to add, delete, connect and disconnect those instances of CElements. Do I really need to define struct Vertex which has pt to CElement instance or there is a more elegant way? – dodol Jun 23 '10 at 09:04

2 Answers2

59

I don't understand what you want to do exactly. Do you want to associate some data to vertices? Then use bundled properties.

//Define a class that has the data you want to associate to every vertex and edge
struct Vertex{ int foo;}
struct Edge{std::string blah;}

//Define the graph using those classes
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS, Vertex, Edge > Graph;
//Some typedefs for simplicity
typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
typedef boost::graph_traits<Graph>::edge_descriptor edge_t;

//Instanciate a graph
Graph g;

// Create two vertices in that graph
vertex_t u = boost::add_vertex(g);
vertex_t v = boost::add_vertex(g);

// Create an edge conecting those two vertices
edge_t e; bool b;
boost::tie(e,b) = boost::add_edge(u,v,g);


// Set the properties of a vertex and the edge
g[u].foo = 42;
g[e].blah = "Hello world";

The are other ways to set the properties, but there you a have an example to bootstrap.

I hope I didn't misunderstand the question.

Zoe
  • 27,060
  • 21
  • 118
  • 148
Tristram Gräbener
  • 9,601
  • 3
  • 34
  • 50
  • 2
    I think that instead of edge_t e = boost::add_edge(u,v,g); one should write edge_t e; bool added; boost::tie(e,added) = boost::add_edge(u,v,g); – dodol Jun 23 '10 at 11:28
  • 2
    @Tristram "easier than using bundled properties" -- what you've described in this answer exactly *IS* bundled properties. =) – wjl Jul 19 '13 at 14:35
  • Is there a way to dynamically create object edge(u,v) and lookup its bundled property? This would be done in a different function that doesn't have boost::tie(e,b) = boost::add_edge(u,v,g); available, only vertex indices. – Budric Apr 18 '16 at 18:29
  • is it possible gven my vertex data `int foo` to find the vertex descriptor which has already been added to the graph? – fferri Jan 20 '18 at 13:24
11

Note that Boost.Graph has overloads which allow to simplify Tristram's answer:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
#include <iostream>

int main()
{
    struct Vertex { int foo; };
    struct Edge { std::string blah; };

    using namespace boost;
    using graph_t  = adjacency_list<listS, vecS, directedS, Vertex, Edge >;
    using vertex_t = graph_traits<graph_t>::vertex_descriptor;
    using edge_t   = graph_traits<graph_t>::edge_descriptor;

    //Instantiate a graph
    graph_t g;

    // Create two vertices in that graph
    vertex_t u = boost::add_vertex(Vertex{123}, g);
    vertex_t v = boost::add_vertex(Vertex{456}, g);

    // Create an edge conecting those two vertices
    boost::add_edge(u, v, Edge{"Hello"}, g);

    boost::write_graphviz(std::cout, g, [&] (auto& out, auto v) {
       out << "[label=\"" << g[v].foo << "\"]";
      },
      [&] (auto& out, auto e) {
       out << "[label=\"" << g[e].blah << "\"]";
    });
    std::cout << std::flush;
}

Output:

digraph G {
0[label="123"];
1[label="456"];
0->1 [label="Hello"];
}
Jean-Michaël Celerier
  • 7,412
  • 3
  • 54
  • 75