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_descriptor
或edge_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 Graph Library 创建 named_graph?