1. 前期废话
这个文章主要是自己在学习和应用图论知识时随手做的一些记录,网上有很多boost—Grpah库的教程,还有官方教程,各取所需,学到知识就好!如果帮到了你,请点赞关注哈哈哈哈=_=!
2. Boost图形库BGL简介
BGL(Boost Graph Library)库是一个Boost库下的针对图结构和算法设计的泛型编程的库,在很多方面都和STL标准库有痕多相似之处。且Boost库本身具有跨平台特性,编译安装什么的都很方便快捷,至少我自己觉得用起来挺好用的。目前针对 图 结构的实现肯定有很多库或者很多实现,选自己觉得适合的就好。我之所以想用BGL是因为我本来已经配置安装了Boost库,正好BGL支持图的结构和算法,且“BGL库具有1)算法/数据结构的可操作性;2)函数对象的扩展性;3)原色类型参数化 等特点”(这些是来自BGL的官方文档的介绍hhhhh)。
2.1 BGL中一些名词的概念
2.1.1 Vertex
当然就是 图 中的每个节点(顶点)啦
2.1.2 Vertex descriptors
这个我理解为是节点的描述符(描述子),参考文档中(A vertex descriptor is a handle to a vertex within a graph)说这个是图中节点的操作句柄。
作用嘛有两个:① 在两个节点之间添加 边 Edge; ② 获取节点的属性信息,比如有向图中某个节点的出度、入度等;
2.1.3 Vertex iterators
节点迭代器。迭代器在STL中很常见,相关知识网上也一大堆。BGL中“无法直接访问节点”,听起来很离谱,但是可以通过这个节点迭代器实现: 首先从图中获取一个节点迭代器对(Vertex iterator pair),然后可以对迭代器进行解引用来获取节点描述子Vertex descriptor。
2.1.4 Vertices
这个玩意翻译过来跟节点的意思一样,但是BGL中这个东西和vertex不一样。结合上一个节点迭代器,通常会使用verices()函数来获取Vertex iterator pair,只要知道这个就行了...(好敷衍=_=).这个函数获取的节点迭代器队,其first元素(注意是一个Vertex Descriptor类型)指向图的第一个节点,second元素指向最后一个节点。这两个玩意有啥用?用过STL就知道,肯定是方便遍历所有的节点啦~
2.1.5 Edge descriptors
理解了节点描述符,这个对应就是边描述符,参考文档中(An edge descriptor is a handle to an edge within a graph. They are similar to vertex descriptors)说这个是图中边的操作句柄。
作用是为了获取边的属性信息,比如有向图中某个边的名字等;
2.1.6 in_degree
入度,某个节点上从别的节点“进入”的边的个数,即number of incoming connections
2.1.7 out_degree
出度,某个节点上从该点“出发”到别的节点的边的个数,即number of outgooing connections
2.1.8 degree
入度 + 出度
2.2 基础函数
2.2.1 创建空图
boost::adjacency_list <boost::vecS , boost::vecS , boost::undirectedS> myEmptyGraph;
这是利用邻接表方式创建的,同样还有通过邻接矩阵创建的方式。
这里<boost::vecS , boost::vecS , boost::undirectedS>中三个模板参数分别用于指定边、节点、图是否有向等属性,vec表示节点用std::vector类型存储,S表示selected,组合起来就是边用选中的vector类型存储。
2.2.2 获取图中 节点、边 总数
boost::num_vertices ( g )
boost::num_edges ( g )
返回一个无符号整型值。
2.2.3 创建节点
boost::add_vertex ( g )
返回一个节点描述符(Vertex Descriptor)对象
2.2.4 获取节点迭代器
vertices ( g ),注意不是 boost::vertices (g)
返回一个节点描述符对(Vertex Descriptor pair)对象, first和second分别指向首、尾的节点
2.2.5 创建边
boost::add_edge ( vd_a, vd_b, g )
返回一个std::pair, fist元素指向创建的边描述符(edge descriptor),second元素为是否创建成功的bool值,如果边已经存在则会创建失败。注意,这里输入的两个节点的参数类型是vertex descriptor类型哦!
2.2.6 获取边迭代器
edges ( g ),注意不是 boost::edges (g)
返回一个边描述符对(Edge Descriptor pair)对象, first和second分别指向首、尾的边
2.2.7 计算出度
out_degree(vd, g),注意不是 boost::out_degree(vd, g)
返回一个整型值,输入为节点的迭代器,图
2.2.8 判断两个节点之间是否存在边(是否连通)
edge(vd1, vd2, g),注意不是 boost::edge(vd1, vd2, g)
返回一个std::pair, first是边描述符,second是bool值是否存在,存在这个边返回true,不存在返回false
2.2.9 两个图是否同形的
boost::isomorphism(g1, g2)
返回一个布尔值,如果两个图有相同的形状,则返回true,反之返回false
2.2.10 求图中的连通的部分
std::vector<int> component(boost::num_vectices( G ));
int num = connected_components(G, &component[0]);
返回一个整数值,是连通部分的数量。其中component中存放每个节点对应的连通部分的序号
算法复杂度 O(|V| + |E|)
2.2.11 输出图到文本的dot文件(或显示在屏幕上)
boost::write_graphviz(std::ofstream f, graph &g);
输入是一个输出的文件流 f 和 需要输出的图 g,这里输出流也可以是std::cout,这样就会显示在屏幕上。
输出的dot文件的格式为:
digraph G {
0;
1;
0->1;
1->0;
1->1;
}
从dot文件内容可以看到,只能输出图的结构,但属性信息不会输出!!!
2.2.12 从dot文件导入图
std::ifstream f ( dot_filename.c_str() ) ;
auto g = create_empty_directed_graph ( ) ;
boost::dynamic_properties dp (boost::ignore_other_properties) ;
boost::read_graphviz ( f , g , dp ) ;
......写不动了,未完待续....