【问题标题】:BGL indexing a vertex by keysBGL 通过键索引顶点
【发布时间】:2015-08-30 11:45:36
【问题描述】:

我的要求是有一个图结构,其中每个顶点都由boost::uuids::uuid 唯一标识。所有顶点都有一个颜色属性,相似类别的顶点将根据该属性进行分组。我不是在处理静态地图,顶点和边将被动态创建和删除。

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;

constructor 我正在创建所有 3 个地图

_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);

同时添加一个顶点

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;
}

列出顶点的 UUID

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; 

这样我总是遍历图的顶点并获取它的属性。但是我也想要另一种方式。从 UUID 到顶点,例如并行 std::map,它将通过添加/删除操作或类似操作自动更新。

此外,我无法保留外部 std::map 并手动同步,因为 boost::adjacency_list&lt;boost::listS, boost::listS&gt;::vertex_descriptor 的计算结果为 void*,我需要序列化支持。

下面的事情是否可行

  1. 通过boost::vertex_index_t值查找顶点
  2. 遍历boost::property_map
  3. 将外部std::mapbimapindex 属性同步

【问题讨论】:

    标签: c++ boost boost-graph


    【解决方案1】:

    我记得图书馆有一个 labeled_graph 实用程序大致支持这个。它具有很高的便利性,我似乎记得它在效率方面不太有趣¹。应该有一个使用它的示例:

    无论如何(并参考您之前的问题),您当然可以使用外部属性映射。这有好处:

    • 您可以随时保留图表中没有的条目
    • 你可以有你需要的反向索引,参见例如

    回答项目符号:

    1. 通过boost::vertex_index_t值查找顶点

      是的,但是如果您想提高效率,确实需要为反向查找提供外部映射使用您自己的数据结构并将其调整为model the Graph Concepts you require(更多工作,显然)

    2. 遍历boost::property_map

      你可以。使用boost::get(tag, graph) 获取属性映射,遍历您要访问的所有实体并为每个属性调用属性映射。例如

      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) << "\n";
      
    3. 将外部std::mapbimapindex 属性同步

      上面的链接应该会给你一些想法


    ¹这可以解释我自己没有使用它。

    【讨论】:

    • 在 (2) 中不是迭代 property_map,而是迭代 vertices()。我认为会有一个multimapstd::pair 类似的接口,如value_type 与(3)问题是,使用地图我需要像vertex_descriptor 这样的东西来稳定。而对于稳定的vertex_descriptor,需要使用listS 而不是vecS。但是 listS vertex_descriptor 的计算结果为 void* 我无法理解这个悖论。因为如果将void* 存储在std::map 中,它将无法序列化。 SO中还有其他问题说labeled_graph不可序列化
    • 在 (1) boost::vertex_index_t 找到顶点的低效方法是什么?对vertices() 进行线性搜索(不是按索引查找顶点)?
    • 没有悖论。除非它们是顶点 ID,否则序列化顶点描述符根本没有意义。如果没有,您 - 必须 - 添加一个顶点 ID 并使用它。它总是这样工作。所以,做你平时做的事。当你陷入困境时,编程你的出路。这是我的现场尝试:livecoding.tv/sehe
    • @NeelBasu 我无法让它工作:(如果我能让重载解析阻止程序工作,我会继续。现在是凌晨 1:46,我称之为退出:((中级:coliru.stacked-crooked.com/a/9df3b2a25a185d20
    • 简短的想法是只拥有一个外部bimap(这样你就有你的查找)。对于序列化,不要序列化原始 bimap,而只需在加载顶点及其属性后构建 bimap。
    猜你喜欢
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多