Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
394 views
in Technique[技术] by (71.8m points)

c++ - Boost Graph accessing properties through vertex_descriptor

I have my custom vertex and edge properties

namespace boost { 
    enum vertex_diagonal_t{vertex_diagonal = 999};
    BOOST_INSTALL_PROPERTY(vertex, diagonal);
}
namespace boost { 
    enum edge_dominance_t{edge_dominance = 998};
    BOOST_INSTALL_PROPERTY(edge, dominance);
}

I create my adjacency list with boost::property

typedef boost::adjacency_list<
      boost::listS, 
      boost::vecS,
      boost::bidirectionalS,
      boost::property<boost::vertex_diagonal_t, const khut::diagonal*>,
      boost::property<boost::edge_dominance_t,  float>
    > diagonal_dominance_graph;
typedef boost::property_map<diagonal_dominance_graph, boost::vertex_diagonal_t>::type diagonal_map_type;
typedef boost::property_map<diagonal_dominance_graph, boost::edge_dominance_t>::type  dominance_map_type;

Now I want to loop through my own containers and add vertex

diagonal_dominance_graph graph;
  for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i){
    diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);

    //>> ?? HOW CAN I write Properties to dia_vertex HERE ?

    //boost::property<boost::vertex_diagonal_t, const khut::diagonal*> p;
    //boost::put(p, dia_vertex);

  }

What I am not getting is How can I set properties of a vertex through vertex_descriptor. may be I am missing a simple function.

Please I don't need anything that makes BGL even more complex, or something that cleans and restructures the types in my example. I just need to know how to read/write properties through a vertex_descriptor or edge_descriptor

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're using property lists: they're documented here.

So in your example, you'd use

diagonal_map_type  vp = get(boost::vertex_diagonal, graph);

using storage_type = std::vector<int>;
storage_type repo_begining(10);

for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i) {
    diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);


    khut::diagonal* v = nullptr;
    boost::put(vp, dia_vertex, v);
}

// likewise for edges
dominance_map_type ep = get(boost::edge_dominance, graph);

See it Live On Coliru

Bundled Properties

The very same documentation page says:

NOTE: The Boost Graph Library supports two interchangeable methods for specifying interior properties: bundled properties and property lists. The former is easier to use and requires less effort, whereas the latter is compatible with older, broken compilers and is backward-compatible with Boost versions prior to 1.32.0. If you absolutely require these compatibility features, read on to learn about property lists. Otherwise, we strongly suggest that you read about the bundled properties mechanism.

Boost 1.32 dates over 10 years ago! So, I'd suggest bundled properties:

Live On Coliru

#include <boost/graph/adjacency_list.hpp>

namespace khut {
    struct diagonal { };

    struct MyVertexProperties {
        diagonal const* diag_ptr;
    };

    struct MyEdgeProperties {
        float dominance;
    };
}

typedef boost::adjacency_list<
      boost::listS, 
      boost::vecS,
      boost::bidirectionalS,
      khut::MyVertexProperties,
      khut::MyEdgeProperties
    > diagonal_dominance_graph;

#include <iostream>


int main() {
    using namespace boost;

    diagonal_dominance_graph g;

    khut::diagonal d1, d2;
    {
        auto v1 = add_vertex(khut::MyVertexProperties { &d1 }, g);
        auto v2 = add_vertex(khut::MyVertexProperties { &d2 }, g);

        /*auto e1 = */add_edge(v1, v2, khut::MyEdgeProperties { 42.31415926 }, g);
    }

    for(diagonal_dominance_graph::vertex_descriptor vd : make_iterator_range(vertices(g)))
        std::cout << "Is diagonal d1? " << std::boolalpha << (&d1 == g[vd].diag_ptr) << "
";
    for(diagonal_dominance_graph::edge_descriptor ed : make_iterator_range(edges(g)))
        std::cout << "Edge dominance: " << g[ed].dominance << "
";
}

Prints

Is diagonal d1? true
Is diagonal d1? false
Edge dominance: 42.3142

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...