图论是一种数学抽象,它对于解决多种计算机科学问题是非常有用的, Boost.Graph提供了一个基于图论的通用编程接口.
Boost.Graph是一个图的封装,在《数据结构》的教科书里,一般都会讲到数组、链表、队列、堆栈、堆、树、图论等。其中前面几个已经在C++标准库(STL)中实现了(如vector,list,stack,queue,heap等),却没有提供一个与树或图对应的实现,实在说不过去。于是这个艰巨而又光荣的任务就落到了作为标准库的预备役的Boost身上, Boost.Graph诞生啦!
Boost.Graph分成数据结构和算法两个大部分(为了便于区分,后文称"图结构"和"图算法"),其中"图结构"相当于 STL里的容器,自带了邻接表(adjacency_list)、邻接矩阵(adjacency_matrix)和CSR图 (compressed_sparse_row_graph)三种。“图算法”相当于STL里的算法,就象std::sort不能用于std::list 一样,对于不同的“图结构”,“图算法”也有不同的适用范围。
“图算法”的适用范围按“概念(Concept)”划分,“图结构”根据它的结构特点被分为“可变图”、“关联图”、“双向图”、“邻接图”、“点表 图”、“边表图”、“属性图”、“可变属性图”几个概念。一种“图结构”可能支持其中的一部分概念而不支持其它的概念,于是也就决定了这种“图结构”所支 持的“图算法”。
图的概念以及对应的算法:
表格中g为图对象,u,v为源和目标顶点,e为边,iter为边的迭代器类型,p为谓词函数(或函数对象)
概念 Concept | 支持函数 |
---|
可变图(Mutable Graph) 允许添加、删除顶点和边 |
std::pair<edge_descriptor,bool> add_edge(u, v, g); | 加入一条边,返回加入后的边以及是否成功。 (若边已存在且不允许并行边,则返回已存在的边) | void remove_edge(u, v, g); | 删除连接u和v的边 | void remove_edge(e, g); | 同上 | void remove_edge(iter, g); | 同上 | void remove_edge_if(p, g); | 删除所有谓词p为true的边 | void remove_out_edge_if(u, p, g); | 删除所有谓词p为ture的出边 | void remove_in_edge_if(u, p, g); | 删除所有谓词p为trre的入边 | vertex_descriptor add_vertex(g); | 添加一个顶点,返回加入的顶点 | void clear_vectex(u, g); | 删除u上的所有边 | void remove_vectex(u, g); | 删除顶点u,注意删除顶点之前要确保该顶点没有边与之连接,否则会出现未定义的行为。典型的用法是在 remove_vectex前调用clear_vectex。 |
|
关联图(Incidence Graph) |
vertex_descriptor source(e, g); | 返回e边上的起源顶点 | vertex_descriptor target(e, g); | 返回e边上的目标顶点 | std::pair<out_edge_iterator, out_edge_iterator> out_edges(u, g); | 以边迭代器对的形式返回顶点u上的所有出边 | degree_size_type out_degree(u, g); | 返回顶点u的出度 |
|
双向图(Bidirectional Graph) |
std::pair<in_edge_iterator, in_edge_iterator> in_edges(v, g) | 以边迭代器对的形式返回顶点v上的所有入边 | degree_size_type in_degree(v, g) | 返回顶点v的入度 | degree(v, g) | 返回入度+出度 |
|
邻接图(Adjacency Graph) |
std::pair<adjacency_iterator, adjacency_iterator> adjacent_vertices(v, g) | 以顶点迭代器范围的形式返回顶点v上的所有邻接点。 |
|
点表图(Vertex List Graph) |
std::pair<vertex_iterator, vertex_iterator> vertices(g) | 以顶点迭代器范围的形式返回所有顶点 | vertices_size_type num_vertices(g) | 返回顶点数 |
|
边表图(Edge List Graph) |
std::pair<edge_iterator, edge_iterator> edges(g); | 以边迭代器的形式返回所有边 | edges_size_type num_edges(g); | 返回边数 | vertex_descriptor source(e, g); | 返回e边上的起源顶点 | vertex_descriptor target(e, g); | 返回e边上的目标顶点 |
|
属性图(Property Graph) 可以为每个顶点和边加入附加属性 |
get(p, g) | 得到图g的属性p的值 | get(p, g, x) | 得到顶点或边x的属性p的值 | put(p, g, x, v) | 设置属性值 |
|
可变属性图(Mutable Property Graph) |
std::pair<edge_descriptor, bool> add_edge(u, v, ep, g) | 加入边,顺便给属性ep赋值 | vertex_descriptor add_vertex(vp, g) | 加入顶点,顺便给属性vp赋值 |
|