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
115 views
in Technique[技术] by (71.8m points)

c++ - BGL indexing a vertex by keys

My requirement is to have a graph structure where each vertex is uniquely identified by a boost::uuids::uuid. All vertices have a color property by which vertices of similar category will be grouped. I am not working on a static map, vertices and edges will be created and removed dynamically.

typedef boost::adjacency_list<
      boost::listS,
      boost::listS,
      boost::bidirectionalS,
      boost::property<boost::vertex_index_t, boost::uuids::uuid, 
        boost::property<boost::vertex_color_t, resource_color,
          boost::property<boost::vertex_underlying_t,   boost::shared_ptr<actual_object*> > > >,
      detail::edge_property
      > graph_type;
graph_type _graph;
boost::property_map<graph_type, boost::vertex_index_t>::type    _index_map;
boost::property_map<graph_type, boost::vertex_color_t>::type    _color_map;
boost::property_map<graph_type, boost::vertex_underlying_t>::type   _underlying_map;

In constructor I am creating all 3 maps

_index_map = boost::get(boost::vertex_index_t(), _graph);
_color_map = boost::get(boost::vertex_color_t(), _graph);
_underlying_map = boost::get(boost::vertex_underlying_t(), _graph);

while adding a vertex

add_resource(resource_color c, actual_object* o){
  graph_type::vertex_descriptor v = boost::add_vertex(o->uuid(), _graph);
  _color_map[v] = c;
  _underlying_map[v] = o;
}

For listing UUID's of a vertex

uuid_list list;
boost::graph_traits<graph_type>::vertex_iterator vi, vi_end;
for(boost::tie(vi, vi_end) = boost::vertices(_graph); vi != vi_end; ++vi){
  list.push_back(_index_map[*vi]);
}
return list; 

This way i am always iterating through vertices of the graph and getting its properties. However I want the other way too. From UUID to vertex like a parallel std::map which will be auto updated with add/remove operations or somethign similar.

Also I cannot keep an external std::map and sync manually, because boost::adjacency_list<boost::listS, boost::listS>::vertex_descriptor evaluates to void* and I need serialization support.

So is the following things doable

  1. find vertex through boost::vertex_index_t value
  2. iterate through a boost::property_map
  3. synchronizing an external std::map or bimap with index property
See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

I remember the library has a labeled_graph utility that supports this roughly. It has a high convenience factor and I seem to remember it being less interesting in terms of efficiency1. There should be a sample using it:

Regardless (and referring back to your previous question) you can certainly use an external property map. This has benefits:

  • you can keep entries that aren't in the graph at all times
  • you can have the reverse index that you require, see e.g.

    • Cut set of a graph, Boost Graph Library (where it is used to get reverse-lookup of the colour map).

      It also contains an equivalent approach but using Boost Multi-index Containers, which is much more flexible even

Answer bullets:

  1. find vertex through boost::vertex_index_t value

    Yes, but if you want to be efficient, indeed you need to either have an external mapping for the reverse lookup OR use your own datastructure and adapt it to model the Graph Concepts you require (much more work, obviously)

  2. iterate through a boost::property_map

    You can. Use boost::get(tag, graph) to get the property map, iterate across all entities you want to visit and invoke the property map for each property. E.g.

    boost::property_map<Graph, boost::vertex_index_t>::type pmap = boost::get(boost::vertex_index, graph);
    boost::graph_traits<Graph>::vertex_iterator b, e;
    for (boost::tie(b,e) = boost::vertices(graph); b!=e; ++b)
        std::cout << "The vertex ID is: " << boost::get(pmap, *b) << "
    ";
    
  3. synchronizing an external std::map or bimap with index property

    The above links should give you ideas


1 that would explain I haven't used it myself.


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

...