Boost Graph Library:可以将Bundled Properties与Interior属性结合起来吗?

时间:2013-12-06 01:51:10

标签: c++ boost-graph

我正在使用此typedef作为我的BGL图表类型Graph,使用struct VertexProperty作为捆绑的顶点属性:

struct VertexProperty {
    BeamType beam;
    size_t index;
};

typedef typename boost::adjacency_list<
        boost::listS,
        boost::listS,
        boost::bidirectionalS,
        VertexProperty
> Graph;

在我的项目最近更改之前,我一直在使用VertexProperty::index构建two_bit_color_map以便与depth_first_search一起使用:

auto colorMap = boost::make_two_bit_color_map(
        boost::num_vertices(graph_),
        get(&VertexProperty::index, graph_));

graph_参数是上面类型Graph的成员变量)。我最近的更改重新定位VertexProperty::index来存储从文件读入的顶点索引号,而不是由我的代码自动生成。我的代码以前一直在创建这些索引作为基于0的连续索引,对于添加到graph_的每个新顶点递增。随着变化,我希望不再假设指数是连续的,或者它们将保持小于graph_.size() - 1;我只是不想把这个约束放在用户身上。但是,我继续使用Vertex::index作为two_bit_color_map的属性,这导致运行时断言失败,并显示以下消息:

Assertion failed!

Program: D:\school\thesis\code\build\test\bin\testChain.exe
File: D:\programming\lib\boost\boost_1_54_0/boost/graph/two_bit_color_map.hpp, Line 72

Expression: (std::size_t)i < pm.n

我知道我的VertexProperty::index值高于或等于graph_.size();我的结论是正确的,这是导致断言失败的原因吗?如果对make_two_bit_color_map使用的索引属性有任何此类限制,我在BGL文档中找不到。

所以,我的主要问题是:是否可以同时使用内部属性,特别是property<vertex_index_t, int> 捆绑的顶点属性与BGL图,或者是我坚持一个或另一个? (我想避免再次使用VertexProperty中的新成员实现连续索引)。我想这可能看起来像这样,但可能还有其他确切的语法:

typedef typename boost::adjacency_list<
        boost::listS,
        boost::listS,
        boost::bidirectionalS,
        property<vertex_index_t, int, property<VertexProperty>>
> Graph;

1 个答案:

答案 0 :(得分:4)

我认为你正在追逐一个错误的问题。

大多数BGL搜索算法需要映射“索引” - &gt; “vertex”,其中索引在区间[0,num_vertices(g))中变化。例如,DFS,BFS,连接组件,A *等需要首先将每个顶点初始化为“白色”。相反,它们基本上使用大小为num_vertices(g)的矢量。

在BGL中,这个中心映射称为“vertex_index”属性映射,如果此属性映射不正确,算法将无法工作。

因此,您的任务AFAICT是确保您能够以连续的方式正确枚举顶点。为此,通常需要向量与一些额外的哈希或STL映射的组合。

在任何情况下,当你修复这个索引映射问题时,你可能会得到一些实现映射的类。然后你的下一步将是教Boost这是你的顶点索引属性。

如果您的类MyMappingClass表现为关联容器(即实现为STL映射,或Boost unordered_map),则可以使用成语make_assoc_property_map(mymap)将其传递给类似DFS的算法,其中mymap的类型为MyMappingClass。

或者,您可以采用下面描述的更精细但更灵活的方式来实现。这种灵活性可以转化为更高效的代码。

由于此属性通常是只读的,因此您可以添加如下代码:

namespace boost {
template<>
struct property_map< MyGraph, vertex_index_t > {
    typedef MyMappingClass const_type;
    //typedef const_type type; 
    //-- we do not define type as "vertex_index_t" map is read-only 
};
}

接下来,您的类MyMappingClass可能是一个完全兼容的BGL属性映射,这意味着它会有一些声明,如

class MyMappingClass
{    
public:    
    typedef readable_property_map_tag category; 
    typedef int value_type;
    typedef value_type reference;
    typedef MyGraph::vertex_descriptor key_type;     
};

此外,要使用这种符合BGL的属性映射,必须提供两个不同的“get”函数:首先是如何从图中“获取”属性映射(如果你使类MyMappingClass为a,则可能是不必要的或微不足道的图的属性)。

第二个函数是如何从属性键的给定值(在[0,num_vertices(g))区间中的“整数”中“获取”属性值(也称为“vertex_descriptor”)。

第二个函数可以有一个类似于以下的原型:

MyMappingClass::value_type //aka index
get(  MyMappingClass mymap,
      MyMappingClass::key_type key) //aka vertex_descriptor  

(注意,根据BGL,MyMappingClass应该是轻量级和可复制的构造)。