转自:http://shanzhizi.blog.51cto.com/5066308/942970

本文是一篇译文,来自:http://blog.csdn.net/jjqtony/article/details/1555965

本文翻译自"Manipulating C++ Graph Data Structures with the Boost Graph Library",原文请见:

http://www.informit.com/articles/article.asp?p=673259&seqNum=4

使用Boost创建一个简单的图

如果你不得不使用算法,你要么自己构建图数据结构,或者使用第三方库。本文所使用的是Boost库。让我们通过第一个例子来展示如何使用Boost库以支持图算法。

一般地,在计算机中可以表示为一组顶点和一组连接顶点的边的集合;边简单地表示为顶点对。进一步每一个顶点和每一条边可能还依附着额外的数据,比如对边来说会有一个数来表示权重。这就是Boost库如何工作的本质。

Boost Graph library是以模板的形式提供的,这意味着你可以在这些模板的基础上创建自己的类型。然而,这些模板的所有类型参数都有默认值,所以你无需任何定制,就可以创建一个图。

下面的一小段代码展示了创建一个图和插入顶点和边的过程,这段代码可以被完全编译,但它除了创建一个图外,并没有做其他什么事情。

#include <iostream>

#include <stdlib.h>

#include <boost/graph/adjacency_list.hpp>

using namespace boost;

int main(int argc, char *argv[])

{

adjacency_list<> mygraph;

add_edge(1, 2, mygraph);

add_edge(1, 3, mygraph);

add_edge(1, 4, mygraph);

add_edge(2, 4, mygraph);

return 0;

}

mygraph变量就是一个图,其类型是adjacency_list,它是图库中基本的图模板类型。在这里我们使用了默认参数,在<>中的参数列表是空的。

函数add_edge是一个模板协助函数,它用来给图增加顶点或边的。为了使用它,你需要传递两个顶点参数,如果在该图中这些顶点不存在,则它们会被加入;然后连接这两个顶点的边也会被加入。这样,上面的这段代码就创建了一个图,它具有四个顶点,编号是1,2,3,4,边有(1,2)、(1,3)、(1,4)、(2,4)。

这只是一个很基本的例子。为了创建更加复杂的,你需要定义更多的数据关联到你的边和顶点,我们将在下一节讨论。

给顶点和边增加属性值

当你使用图,通常你会附加一些信息给顶点和边,图库使用了一个很有趣的方法来做到这一点。诸如名字或颜色信息作为一种属性来存储,一个属性由一个名字(或标识),如距离,和类型,如浮点数或字符串,组成。你可以给顶点和边增加属性。

提示

库中,有几个常用的,已经内建好了的属性标识,如颜色,名字和权重。所有的内建标识都列在在线帮助中,同样你可以在graph/properties.hpp这个头文件中找到它们。它们是用宏的方式来定义的,形成了枚举常量。比如,在properties.hpp中有一行属性定义:

BOOST_DEF_PROPERTY(edge, name);

这个宏的结果是产生了一个枚举常量edge_name,它的类型是edge_name_t。你还能看到其他的内建属性标识定义。

当你定义一个图时,你可以指定跟该图相关联的的属性类型,你也可以加入你很多想要的属性给顶点和边。为了定义属性,首先你需要为每一个属性类型创建一个模板类型,然后在你具现化图之前定义图类型。比如,假设你想每一条边增加距离属性,给每个顶点赋予城市名称,下面的代码就来展示如何定义这两种属性类型:

typedef property<edge_weight_t, int> EdgeWeightProperty;

typedef property<vertex_name_t, std::string> VertexNameProperty;

第一行定义了EdgeWeightProperty类型,模板的第一个参数是这个属性的标识,在这里我们使用的是预先定义好的标识edge_weight_t,它的意思是边的权重,第二个参数是int,意思是这个属性具有一个整型数值。第二行定义了第二个属性,它的标识是vertex_name_t,类型是string。

现在你已经定义好属性,你可以定义一个图类型了:

typedef adjacency_list<vecS, vecS, undirectedS,

VertexNameProperty, EdgeWeightProperty> Graph;

这个定义中的前三个模板参数是预先定义好的,第一和第二个参数(都是vecS)表示我们要求图使用vector来作为图的内部存储方式,第三个参数说明这是一个无向图,第四、五个参数是我们刚刚定义的属性类型,前者是顶点的属性类型,后者是边的属性类型。

这个时候,你可能会有疑问:如何给顶点和边指定不止一个属性类型呢?事实上,可以把属性串联在一起。基本类型模板包含了一个模板参数,它可以是你已经定义的属性类型。下面是顶点类型定义,不过,这时我们定义了为顶点定义了两个属性,一个是name,一个是index(下面的代码使用了预定义的标识vertex_index2_t):

typedef property<vertex_index2_t, int>

VertexIndexProperty;

typedef property<vertex_name_t, std::string,

VertexIndexProperty> VertexNameProperty;

注意

这里使用的是vertex_index2_t,而不是vertex_index_t,这是因为后者有一些与它有关的内建模板已经做了我们正在做的。

我们首先定义了index属性,不过这个顺序无关紧要。属性VertexNameProperty就包含了VertexIndexProperty作为它的第三个参数,这样就创建了一个链。然后你也可以象前面一样将VertexNameProperty作为第四个参数传递给图定义。

你也可以精简你的代码,不过精简过的代码对于图库初学者来说可读性要差一些,虽然一旦你理解了属性的这种机制后,这种精简的过程也是十分的直接。

typedef property<vertex_name_t, std::string,

property<vertex_index2_t, int> > VertexProperties;

我们重命名了类型VertexProperties,这是由于它现在包含了两种不同的属性。有个地方请大家注意,C++标准要求在两个>之间要有空格,这是为了同>>运算符区分开来。别忘了这个空格,否则你将得到编译错误。

操纵属性

为了访问http://shanzhizi.blog.51cto.com/中的属性,你需要从图库中获得一个协助对象,对于每一种属性类型你都需要一个协助对象。这些对象是模板对象,一旦你创建了一个图类型的实例后,你就可以获得它。下面是获得前一节定义的三个属性的代码:

property_map<Graph, vertex_name_t>::type

city_name = get(vertex_name, g);

property_map<Graph, vertex_index2_t>::type

city_index2 = get(vertex_index2, g);

property_map<Graph, edge_weight_t>::type

edge_distance = get(edge_weight, g);

别担心这里的函数名字是一个很通用的单词get,这个函数是得到很好定义的模板函数,它会编译的很好。

第一条语句创建了一个对象来获得vertex_name属性,仔细观察这条语句的参数,在最左边,传递给模板的参数Graph是前面定义过的,紧跟着是属性的标识vertex_name_t;右边,在get函数里,第一个参数并不是属性的标识名,而是一个与该属性相关的枚举类型vertex_name。每一个预定义的标识名都有一个枚举类型。get函数的第二个参数是图对象g。

请记住,这里的三个调用你可以用来获得顶点的属性和边的属性,虽然我们这里给出的代码片段是针对顶点来做的。下面的一行代码将来要用于获得属性:

std::cout << city_name[*vp.first];

这里的vp.first是一个指向vertex的指针。对象city_name象map一样地工作,它将一个顶点对象作为参数,然后返回该顶点合适的属性,在这个例子中,返回的是城市名。

加入顶点和边

在你指定了属性类型和定义了图类型之后,你已经可以去创建一个图实例,然后向图结构中加入顶点和边,这些顶点和边是具有你所定义的属性的。

【转】使用Boost Graph library(一)的更多相关文章

  1. Boost Graph Library使用学习

    Boost Graph Library,BGL 使用学习 探索 Boost Graph Library https://www.ibm.com/developerworks/cn/aix/librar ...

  2. Boost Graph Library materials

    Needed to compute max flow in a project and found the official document of BGL to be rather obscure, ...

  3. 【转】使用Boost Graph library(二)

    原文转自:http://shanzhizi.blog.51cto.com/5066308/942972 让我们从一个新的图的开始,定义一些属性,然后加入一些带属性的顶点和边.我们将给出所有的代码,这样 ...

  4. boost graph

    Boost Graph provides tools to work with graphs. Graphas are two-dimensional point clouds with any nu ...

  5. boost random library的使用

      生成满足一定分布的随机数,是统计模拟.系统仿真等应用中最基本的要求.matlab中提供了函数可以生成各种常见分布的随机数,c++使用boost random库也可以很容易实现. 一.例子 boos ...

  6. 转债---Pregel: A System for Large-Scale Graph Processing(译)

    转载:http://duanple.blog.163.com/blog/static/70971767201281610126277/   作者:Grzegorz Malewicz, Matthew ...

  7. 译:Boost Property Maps

    传送门:Boost Graph Library 快速入门 原文:Boost Property Map 图的抽象数学性质与它们被用来解决具体问题之间的主要联系就是被附加在图的顶点和边上的属性(prope ...

  8. Pregel: A System for Large-Scale Graph Processing(译)

    [说明:Pregel这篇是发表在2010年的SIGMOD上,Pregel这个名称是为了纪念欧拉,在他提出的格尼斯堡七桥问题中,那些桥所在的河就叫Pregel.最初是为了解决PageRank计算问题,由 ...

  9. boost库的安装,使用,介绍,库分类

    1)首先去官网下载boost源码安装包:http://www.boost.org/ 选择下载对应的boost源码包.本次下载使用的是 boost_1_60_0.tar.gz (2)解压文件:tar - ...

随机推荐

  1. 如何在MFC对话框之间自定义消息传递

    在MFC项目开发中,涉及到不同模块间数据信息的传递,如用户在登录界面成功登录后向系统管理模块发送用户名和密码等信息. 首先,需明确以下两点: 谁要发送这个消息--消息发送方 谁要接受这个消息--消息接 ...

  2. EF(ServerFirst)执行存储过程实例1(带输出参数)

    1.不含动态sql.带输出参数存储过程调用实例 a.存储过程代码: b.EF自动生成代码(包括对应ObjectResult的实体模型): c.调用存储过程代码实例:  总结: ObjectParame ...

  3. oracle tns

    oracle tns 是oracle提供的服务名,设置方法,oracle安装根目录---product----版本选择11.2.0----client1---NETWORK---ADMIN---tns ...

  4. SQL学习之组合查询(UNION)

    1.大多数的SQL查询只包含从一个或多个表中返回数据的单条SELECT语句,但是,SQL也允许执行多个查询(多条SELECT语句),并将结果作为一个查询结果集返回.这些组合查询通常称为并或复合查询. ...

  5. LayoutInflater作用及使用

    作用: 1.对于一个没有被载入或者想要动态载入的界面, 都需要使用inflate来载入. 2.对于一个已经载入的Activity, 就可以使用实现了这个Activiyt的的findViewById方法 ...

  6. PHP并发最佳实践

    直接参考大牛的: http://www.searchtb.com/2012/06/rolling-curl-best-practices.html

  7. css hr 设置

    http://www.sovavsiti.cz/css/hr.html http://adamculpepper.net/blog/css/hr-tag-css-styling-cross-brows ...

  8. BZOJ 1103 [POI2007]大都市meg(树状数组+dfs序)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1103 [题目大意] 给出一棵树,每条边的经过代价为1,现在告诉你有些路不需要代价了, ...

  9. uber奖励和账单详解

    为了让各位车主轻松理解奖励政策和账单明细的核算方法,我们特意制作#奖励详解#的专题文章,保证您五分钟内掌握看懂账单的全部要领和诀窍. 第一部分:收入说明 看到收入说明的账单是不是有些晕呢,来来,我们一 ...

  10. hdu4491 Windmill Animation(计算几何)

    Windmill Animation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...