Boost图库:可以将绑定属性与内部属性相结合

Boost Graph Library: possible to combine Bundled Properties with Interior Properties?

本文关键字:属性 内部 相结合 绑定 图库 Boost      更新时间:2023-10-16

我将此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:schoolthesiscodebuildtestbintestChain.exe
File: D:programminglibboostboost_1_54_0/boost/graph/two_bit_color_map.hpp, Line 72
Expression: (std::size_t)i < pm.n

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

所以,我的主要问题是:是否可以同时使用内部属性,特别是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;

我认为你在寻找一个错误的问题。

大多数BGL搜索算法需要映射"索引"-->"顶点",其中索引在区间[0,num_vertices(g)中变化。例如,DFS、BFS、连接组件、a*等需要首先将每个顶点初始化为"白色"。相反,它们本质上使用num_verties(g)大小的向量。

在BGL中,这个中心映射被称为"顶点索引"属性映射,如果这个属性映射不正确,算法就无法工作。

因此,您的任务,AFAICT,是确保您可以以连续的方式正确枚举顶点。通常情况下,需要将向量与一些额外的哈希或STL映射相结合。

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

如果您的类MyMappingClass表现为关联容器(即实现为STL映射或Boost unordereded_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的属性映射,必须提供两个不同的"获取"函数:第一个是如何从图中"获取"属性映射(如果将类MyMappingClass作为图的属性,则可能是不必要的或琐碎的)。

第二个函数是如何从属性键的给定值(即区间[0,num_vertices(g)中的整数)中"获取"属性值(即"顶点描述符")

第二个功能可以有一个类似于以下的原型:

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

(注意,根据BGL,MyMappingClass应该是一个轻量级的、可复制的)。