首页 文章

BGL:如何从顶点迭代器获取自定义顶点属性类实例?

提问于
浏览
1

我正在学习使用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文档或其他任何地方找到它 .

谢谢你的帮助 .

1 回答

  • 6

    使用 g[*vert_i].attribute1 应该有效 . 这是指定它的方式,它确实有效 . 如果您查看bundled properties上的doc页面,它会说:

    要访问特定边或顶点的捆绑属性,请使用要访问其捆绑属性的边或顶点的描述符下标图 .

    他们举了一个例子:

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

    还有一个不受支持的功能(引擎盖下)用于获取整个捆绑包的属性映射,但您无法使用它,因为它不是受支持的接口的一部分 .

相关问题