使用C++ Boost Graph Library 进行社交网络分析入门篇

原创 2016年05月30日 11:19:40

前言:

     社交网络分析是一个常常会遇到的业务问题,故而笔者也一致在不断尝试不同的社交网络分析工具。之前使用过python networkx, igraph C library, 今日再介绍一款C++环境下的分析工具: Boost Graph Library(下文简称BGL), 该库据说可轻松处理百万级别节点规模的网络.  业界对该款工具的评语有:

1. large, stable, efficient
2. Lots of algorithms, graph types
3. Peer-reviewed code with many users, nightly regression testing, etc.
4. Performance comparable to FORTRAN.
本文介绍下该工具的入门操作,如何创建一个网络,并设置节点属性,以及如何读取节点属性。

1. 准备工作


解压后,按以下步骤安装

1. sh ./bootstrap.sh

2. ./b2

2. 创建图

     一般情况下,我们会把网络中的边存放在文件中,然后希望读取该文件后,自动创建相应的图(igraph就是这样处理的),但是悲剧的是,在BGL中,死活没找到直接读文件的接口,于是只能手工逐行读取了。比如, 我们用如下格式准备好一个图中边的列表文件:

v1 v2
v1 v3
v3 v4

现在要做的是,逐行读入,给网络添加节点和边。同时,要注意可能存在重复添加的情况,要做好重复性检测。完整代码如下:

#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
#include <fstream>

using namespace std;
using namespace boost;

int main(int argc, char* argv[]){
    if(argc != 2){
        cout << "Usage: " << argv[0] << " <inputEdgeListFile> " << endl;
        exit(-1);
    }

    typedef adjacency_list<vecS,vecS,undirectedS,property<vertex_name_t,string> > Graph;
    Graph g;
    typedef graph_traits<Graph>::vertex_descriptor vertex_descriptor;
    typedef graph_traits<Graph>::edge_descriptor edge_descriptor;
    typedef graph_traits<Graph>::vertices_size_type vertices_size_type;
    typedef graph_traits<Graph>::edges_size_type edges_size_type;

    string inputEdgeListFile = argv[1];
    ifstream infile(inputEdgeListFile.c_str());
    string startNodeName, endNodeName;
    map<string, vertex_descriptor> name2vertex;
    while(infile >> startNodeName >> endNodeName){
        vertex_descriptor s,e;
        if(name2vertex.find(startNodeName) == name2vertex.end()){
            s = add_vertex(g);
            put(vertex_name,g,s,startNodeName);
            name2vertex[startNodeName] = s;
        }else{
            s = name2vertex[startNodeName];
        }

        if(name2vertex.find(endNodeName) == name2vertex.end()){
            e = add_vertex(g);
            put(vertex_name,g,e,endNodeName);
            name2vertex[endNodeName] = e;
        }else{
            e = name2vertex[endNodeName];
        }

        //test if edge (s,e) exists
        pair<edge_descriptor,bool> edgeFlag = edge(s,e,g);
        if( ! edgeFlag.second){
            add_edge(s,e,g);
        }
    }

    vertices_size_type n = num_vertices(g);
    cout << "图G中节点总数为:" << n << endl;

    edges_size_type m = num_edges(g);
    cout << "图G中边总数为:" << m << endl;

    //如果需访问图中每个节点的属性,可如下操作
    typedef boost::graph_traits<Graph>::vertex_iterator vertex_iterator;
    std::pair<vertex_iterator, vertex_iterator> vi;
    for(vi = vertices(g);vi.first != vi.second; ++ vi.first){
        cout << get(vertex_name,g,*vi.first) << endl;
    }

    return 0;
}

笔者测试了一个节点规模为12W, 边规模为15W的图,用上面程序执行创建图的时间消耗是2秒左右。将这个文件中的边反复copy几份,使文件中行数增长到142W,这时再读取,一来需要遍历的行数增加,二来去重的工作量增加很多,这时执行的时间消耗是15.91s,性能还是蛮不错的。

3. 后记

  • 注意
    typedef adjacency_list<vecS,vecS,undirectedS,property<vertex_name_t,string> > Graph; 
    这一句用于创建一个无向有特征属性的图。而图计算领域中,细节还是蛮多的,比如是否有向图,节点和边是否有属性,是否允许多重边,等。这些都要根据需求定义不同的图类。而BGL中比较灵活的一点就是允许用户自主定义各种节点和边属性。
  • 如果需要遍历图中节点或边,BGL提供了迭代器方法,如 vertices(g)返回是一个pair类型,第一个参数是指向首节点的迭代器,第二个参数是指向末节点的迭代器。如果需要提取属性特征,则使用get(特征名,图对象,节点)的方法。
        typedef boost::graph_traits<Graph>::vertex_iterator vertex_iterator;
        std::pair<vertex_iterator, vertex_iterator> vi;
        for(vi = vertices(g);vi.first != vi.second; ++ vi.first){
            cout << get(vertex_name,g,*vi.first) << endl;
        }
  • 总体上,个人感觉BGL的入门成本比networkx, igraph都要高一些,一来官方文档写得不够通俗,二来市面上能找到的相关文章也较少。同时,BGL的易用性上,也较后两者略不不足,提供的内置算法,也不如后两者丰富。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Boost C++ 库入门

简介: Boost C++ 库(Libraries)是一组扩充C++功能的经过同行评审(Peer-reviewed)且开放源代码程序库。大多数的函数为了能够以开放源代码、封闭项目的方式运作,而授权于B...
  • sinat_20265495
  • sinat_20265495
  • 2016年09月06日 15:04
  • 9436

c++的boost库学习笔记

c++的boost库学习 boost和stlport编译,编译过程好麻烦,根据网上教程和boost完全开发指南,加自己摸索才勉强编译完成,做个笔记总结一下,具体编译方法,暂且不写   1,time...
  • u013013970
  • u013013970
  • 2015年04月18日 08:21
  • 1169

boost中文文档最新版,经典boost教程

  • 2010年08月20日 11:58
  • 19.23MB
  • 下载

boost——入门指南

boost库是一个开源免费的第三方库,它是一个非常优秀的库,是C++标准的最好实践之一,因此也经常被用于商业的开发。所以,如果你是搞C++的,还没有听过或用过boost,你就out了,想想自己是不是跟...
  • luoweifu
  • luoweifu
  • 2015年01月18日 11:21
  • 9894

C++ Boost

Boost准标准库 boost是一个准标准库,相当于STL的延续和扩充,它的设计理念和STL比较接近,都是利用泛型让复用达到最大化。不过对比STL,boost更加实用。STL集中在算法部分,而boo...
  • doc_sgl
  • doc_sgl
  • 2013年10月11日 20:19
  • 6816

c++Boost教程

  • 2013年09月02日 18:44
  • 21.66MB
  • 下载

c++ boost 安装

在这里向大家介绍一下 c++ boost 的安装。我是在cygwin的环境下进行安装的。如果用vs等,大致方法一样     1.首先我们需要download boost文件。可在http://www...
  • scdnshijiemengxiang
  • scdnshijiemengxiang
  • 2012年03月17日 09:32
  • 2510

C++Boost序列化(Serialization)库教程

一个非常简单的情形 非侵入的版本 可序列化的成员 派生类 指针 数组 STL容器 类的版本 把serialize拆分成save/load 档案 输出档案(archive)类似于输出数据流(stream...
  • fanyun_01
  • fanyun_01
  • 2016年09月30日 09:22
  • 1633

【C++多线程编程】Boost线程库

Boost线程库 Bill Kempf 译:伐木工 标准C++线程即将到来。CUJ预言它将衍生自Boost线程库,现在就由Bill带领我们探索一下Boost线程库。 就...
  • yockie
  • yockie
  • 2014年05月26日 00:31
  • 8450

Boost程序库完全开发指南.pdf

  • 2012年11月27日 20:18
  • 21.66MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用C++ Boost Graph Library 进行社交网络分析入门篇
举报原因:
原因补充:

(最多只允许输入30个字)