我正在学习使用Boost Graph Library。我已经定义了一个自定义结构来存储有关顶点的信息,如下所示:Modifying vertex properties in a Boost::Graph。
struct VertexProperties {
int attribute1;
string attribute2;
};
typedef adjacency_list<vecS, vecS, directedS, VertexProperties, no_property> Graph;
我可以像这样迭代图形顶点并修改它们的属性:
for (int i = 0; i < num_vertices(g); i++)
{
g[i].attribute1 = 123;
g[i].attribute2 = "123";
}
但是,当我所有的都是顶点迭代器时,我如何实际获得这些属性(即VertexProperties的相应实例)?
GraphTraits::vertex_iterator vert_i, vert_end;
for (tie(vert_i, vert_end) = vertices(g); vert_i != vert_end; ++vert_i){
//how do i get to "vert_i.attribute1" ?
}
同样的问题适用于边缘和边缘迭代器。它应该很容易,但我似乎无法在BGL文档或其他任何地方找到它。
感谢您的帮助。
答案 0 :(得分:6)
使用g[*vert_i].attribute1
应该有效。这是指定它的方式,它确实有效。如果你查看bundled properties上的文档页面,它会说:
要访问特定边或顶点的捆绑属性,下标您的图形,其中包含您希望访问其捆绑属性的边或顶点的描述符。
他们举了例子:
Graph g;
Graph::vertex_descriptor v = *vertices(g).first;
g[v].name = "Troy";
vertex_iterator
类型应该取消引用vertex_descriptor
,您应该用它来下标到图表中g[v]
。因此,使用g[*vert_i].attribute1
肯定会起作用。如果没有,那么您需要在跟踪器上提交错误。
所以,这也意味着您的原始代码g[i].attribute1
不正确,因为无法保证整数索引必须与该图的vertex_descriptor
类型相同(它只是恰好工作是因为您使用vecS
作为VertexList
参数,这使得vertex_descriptor
成为一个整数,但即使使用vecS
也不一定如此。您应该只使用vertex_descriptor
个对象来索引图形。此外,如果您的g[i]
代码有效,那么g[*vert_i]
也应该有效,除非存在严重的错误,否则根本无法工作而不能工作。
但请注意,我知道在某些条件下禁用了捆绑属性。特别是,它使用了一些编译器可能不支持的技术,这意味着较旧的或外来的编译器可能无法完成这项工作。这是一个缺陷,我希望将来可以通过替代实现来彻底检查当前的adjacency_list
类模板,但是这种激烈的重新设计不太可能在一段时间之前进入BGL。
访问捆绑属性的另一种方法是使用其属性映射,它具有一些讨厌的语法,但可能有更大的工作机会。对于你的例子,它将是这样的:
boost::property_map<Graph, int VertexProperties::*>::type attr1 =
get(&VertexProperties::attribute1, g);
GraphTraits::vertex_iterator vert_i, vert_end;
for (tie(vert_i, vert_end) = vertices(g); vert_i != vert_end; ++vert_i){
put(attr1, *vert_i, 123);
}
还有一个不受支持的功能(引擎盖下)用于获取整个捆绑包的属性映射,但您无法使用它,因为它不是受支持接口的一部分。