使用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 Graph Library 快速入门

Boost Graph Library 快速入门   图领域的数据结构和算法在某些方面比容器更为复杂,图算法在图中移动有着众多的路线,而ST...

C++ Boost graph 深度(广度)优先算法示例

//整理 by  RobinKin from DevonIT.inc#include #include #include #include #include #include #include #in...

Boost C++ 库入门

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

【Boost】C++ Boost库简介

boost是一个准标准库,相当于STL的延续和扩充,它的设计理念和STL比较接近,都是利用泛型让复用达到最大化。不过对比STL,boost更加实用。STL集中在算法部分,而boost包含了不少工具类,...
  • huang_xw
  • huang_xw
  • 2012年09月02日 08:58
  • 11996

boost库之graph入门

#include #include

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Boost Graph

图论是一种数学抽象,它对于解决多种计算机科学问题是非常有用的,Boost.Graph提供了一个基于图论的通用编程接口. Boost.Graph是一个图的封装,在《数据结构》的教科书里,一般都会讲到数组...
  • seamanj
  • seamanj
  • 2016年02月05日 02:21
  • 985

c++的boost库学习笔记

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

boost——入门指南

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

Boost入门

Boost入门向导   简介: boost是一套开源的、高度可移植的C++模板库。它由C++标准委员发起,且里面很多组件有望成为下一代的C++标准库,其地位将会与STL一样。 boost库的英...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用C++ Boost Graph Library 进行社交网络分析入门篇
举报原因:
原因补充:

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