【第22期】观点:IT 行业加班,到底有没有价值?

使用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 快速入门    图领域的数据结构和算法在某些方面比容器更为复杂,图算法在图中移动有着众多的路线,而STL使用的抽象迭代器接口不能有效的支持这些。作为替换,我们...

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

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

boost graph lib 小试牛刀

最近要做社会网络的社区发现,发现用BGL能减少不少代码量。经过一番调研发现BGL封装的很牛叉,Dijkstra等算法统统具备,奈何自己对泛型编程不太熟, 遇到问题还是很纠结。Primer泛型编程、算...

使用Boost Graph library

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

Graph Concepts

Graph Concepts The heart of the Boost Graph Library (BGL) is the interface, or concepts (in the par...

图论(十)最小生成树-Prim算法

前面说过,Prim算法是从顶点着手构建最小生成树的。应该说,Prim算法比Kruskal更简单。我们还是以前面的乡镇假设光纤网络为例: Prim算法工作步骤 (1) 构建全部顶点集V,选取...

图论(九)最小生成树-Kruskal算法

前面说过,Kruskal是从最短边着手构建最小生成树的。其基本过程是:先对图中的所有边按照权重值从小到大进行排序,然后着手选取边构建最小生成树。如果直接从小到大按顺序选取,有可能形成了环,所以对环的处...

Boost Graph Library (BGL)学习:使用Bundled Properties

// 所有原创文章转载请注明作者及链接// blackboycpp(AT)gmail.com// QQ群: 135202158  /* * 文件: Unit1.cpp * 日期: 2008-1...

计算机网络应用层协议分析总结

1、应用层协议原理1.1、网络应用程序体系结构C/S结构,有一个总是打开的主机称为服务器,它服务于来自许多其他称为客户机的主机请求。客户机主机既可能有时打开,也可能总是打开。C/S结构之下,客户机之间...

网络协议分析

前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑。主要是因为对网络协议不太熟悉,对一些概念也没弄清楚。后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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