我正在使用此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;
答案 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应该是轻量级和可复制的构造)。