Boost Graph 通过 vertex_descriptor 访问属性

Posted

技术标签:

【中文标题】Boost Graph 通过 vertex_descriptor 访问属性【英文标题】:Boost Graph accessing properties through vertex_descriptor 【发布时间】:2015-02-26 11:15:14 【问题描述】:

我有我的自定义顶点和边属性

namespace boost  
    enum vertex_diagonal_tvertex_diagonal = 999;
    BOOST_INSTALL_PROPERTY(vertex, diagonal);

namespace boost  
    enum edge_dominance_tedge_dominance = 998;
    BOOST_INSTALL_PROPERTY(edge, dominance);

我用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;

现在我想遍历我自己的容器并添加顶点

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

  

我没有得到的是如何通过vertex_descriptor 设置顶点的属性。可能是我缺少一个简单的功能。

请在我的示例中,我不需要任何使 BGL 更加复杂的东西,或者清理和重组类型的东西。我只需要知道如何通过vertex_descriptoredge_descriptor 读取/写入属性

【问题讨论】:

【参考方案1】:

您正在使用属性列表:它们是documented here。

所以在你的例子中,你会使用

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

Live On Coliru

捆绑属性

同样的文档页面说:

注意:Boost 图形库支持两种可互换的方法来指定内部属性:捆绑属性和属性列表。前者更易于使用且所需工作量更少,而后者与旧的、损坏的编译器兼容,并且向后兼容 1.32.0 之前的 Boost 版本。如果您绝对需要这些兼容性功能,请继续阅读以了解属性列表。 否则,我们强烈建议您阅读捆绑属性机制。

10 年前的 Boost 1.32 日期!所以,我建议捆绑属性:

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) << "\n";
    for(diagonal_dominance_graph::edge_descriptor ed : make_iterator_range(edges(g)))
        std::cout << "Edge dominance: " << g[ed].dominance << "\n";

打印

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

【讨论】:

我没有使用 C++11。是的,我可以使用自己的结构作为捆绑属性。但是如何处理旧的boost::property 东西? (另外,c++ 已经是 c++11 好几年了。我在示例中使用 c++11 的事实不应该影响您的实用性。只需修改需要的内容修改) 是的,我同意使用 boost::property 比使用自己的结构更复杂。但我想知道如何使用 boost::property 来做到这一点。我已经在 So that 中看到了一些以前的答案,而不是专注于实际问题,而是倾向于重构类和问题示例中的 typedef。我想避免的:) @NeelBasu 我已经用我在评论中给出的示例更新了答案。它现在回答了这个问题:) 谢谢。所以你需要在向图中添加任何顶点之前执行boost::get

以上是关于Boost Graph 通过 vertex_descriptor 访问属性的主要内容,如果未能解决你的问题,请参考以下文章

删除顶点并再次添加它会导致 boost::graph 崩溃?

怎样通过boost库的breadth

如何使用 Boost Graph Library 创建 named_graph?

使用Boost Graph库查找连接的组件,顶点和边缘类型为boost :: listS

使用整数索引访问 boost::graph 中的特定边

Boost::graph Dijkstra : 最初填充队列