图的数据结构及算法在许多方面都比图的容器要复杂(一开始就说复杂,:))。STL中的迭代器接口不足够强大,以至于它不能够适用于图的所有算法。因此,我们仿照STL迭代器和STL容器的关系,设计出一个抽象接口来管理图容器(虽然迭代器在其中也启动了很大作用)。图1描述了STL和BGL的这种类似关系
图1: STL和BGL类似处
......
在下面的几节中我们将用BGL构造一个图,并用好几种方式对他进行处理。
构造一个图
在这个例子中我们将用BGL的adjacent_list类模板来揭示BGL中接口的主要思想。adjacent_list类模板是图中adjacent list数据结构的一种泛型。adjacent_list类模板有6个模板参数,但现在我们只需要设置前面3个模板参数,其他参数使用缺省参数。开始的2个模板参数(vecS, vecS)决定了表示图中每个顶点的出边的数据结构和表示图中顶点集合的数据结构;第三个模板参数bidirectionalS表明构造出来的图是一个能同时访问出边和入边的有向图, 第三个模板参数的其他选项有:directedS表明构造一个只能访问出边的有向图,undirectedS表明构造一个无向图。
一旦我们选择了图的类型,我们就可以通过声明一个图对象,并通过MutableGraph的接口(adjacent_list实现了此接口)函数add_edge添加边的方法来创建一个图。
除了使用add_edge()添加边的方法,我们还可以使用图的edge iterator构造器来创建对象,这种方法比add_edge()方法效率高。edge_array对应的指针可以当做edge的迭代器使用,因此我们可以传递edge_array数组的开始地址对应指针和尾部地址对应指针给构造器。
#include <utility> // for std::pair
#include <algorithm> // for std::for_each
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
using namespace boost;
int main(int,char* [])
... {
// create a typedef for the Graph type
typedef adjacency_list<vecS, vecS, bidirectionalS> Graph;
// Make convenient labels for the vertices
enum ...{ A, B, C, D, E, N };
const int num_vertices = N;
const char* name = "ABCDE";
// writing out the edges in the graph
typedef std::pair<int, int> Edge;
Edge edge_array[] =
...{ Edge(A,B), Edge(A,D), Edge(C,A), Edge(D,C),
Edge(C,E), Edge(B,D), Edge(D,E) };
const int num_edges = sizeof(edge_array)/sizeof(edge_array[0]);
// declare a graph object
Graph g(num_vertices);
// add the edges to the graph object
for (int i = 0; i < num_edges; ++i)
add_edge(edge_array[i].first, edge_array[i].second, g);
...
return 0;
}
除了一开始便创建一个拥有一定数量节点的图,也可以通过add_vertex()和remove_vertex()方法增加和删除节点,这些方法也都是MutableGraph的接口。