Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

custom properties for edges in the BGL

I started using the BGL for some graph-related task. I have a large number of edges and each edge has several properties, one of which is its weight. (All properties are floats and ints). Since I never worked with the BGL (and/or similar CPP libraries) before, I'm a bit lost with all these types, classes and how to use it properly.

I add my edges like this:

struct EdgeProperty
{
    int weight;
    float e1;
    float e2;
};

typedef adjacency_list<vecS, vecS, bidirectionalS, no_property, EdgeProperty> Graph;
...
EdgeProperty prop;
node1 = ...;
node2 = ...;
prop.e1 = ...;
prop.e2 = ...;
prop.weight = ...;

add_edge(node1, node2, prop, g);

Then, I need to access my property later, what I am trying to do like this:

property_map<Graph, EdgeProperty>::type EdgeWeightMap = get(EdgeProperty, g);
w = get(EdgeWeightMap,some_edge);

However, this doesn't even compile. It says in the error message:

error: no type named ‘kind’ in ‘struct EdgeProperty’

amongst other errors, which I consider less important right now. I don't know if this is how you would use custom properties. Could you please explain to me the kind error message and how to use custom properties? I couldn't find any documentation (which I understand) on this topic.

like image 892
janoliver Avatar asked Oct 10 '22 14:10

janoliver


1 Answers

Take a look at this code, I believe it explains a few things of its own:

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

namespace bgl = boost;

struct EdgeInfo
{
    int weight;
    float e1;
    float e2;
};

struct EdgeInfoPropertyTag
{
    typedef bgl::edge_property_tag kind;
    static std::size_t const num; // ???
};

std::size_t const EdgeInfoPropertyTag::num = (std::size_t)&EdgeInfoPropertyTag::num;

typedef bgl::property<EdgeInfoPropertyTag, EdgeInfo> edge_info_prop_type;
typedef bgl::adjacency_list<bgl::vecS, bgl::vecS, bgl::bidirectionalS,
    bgl::no_property, edge_info_prop_type> Graph;
typedef bgl::graph_traits<Graph>::vertex_descriptor vertex_descr_type;
typedef bgl::graph_traits<Graph>::edge_descriptor edge_descr_type;

int
main ()
{
    Graph g;
    vertex_descr_type u, v;
    u = add_vertex (g);
    v = add_vertex (g);
    EdgeInfo props;
    props.weight = 3;
    std::pair<edge_descr_type, bool> result = add_edge (u, v, props, g);

    EdgeInfo p = get (EdgeInfoPropertyTag (), g, result.first);
    std::cout << "weight: " << p.weight << std::endl;
}

You need to read about the concepts that BGL is based upon.

This way you can hang any kind of value off of the edge (and similarly for vertex). You could also use the predefined types of properties, like edge_weight_t or edge_name_t I believe.

See also BGL docs about custom edge properties.

like image 198
wilx Avatar answered Oct 13 '22 11:10

wilx