igraph/networkx学习笔记之…

 首先,基本上所有的graph library都有其局限性,不同的数据结构有优点的同时必然有缺点,图算法对数据结构的依赖性构成另一个原因。所以如果是想用一个工具包解决所有的问题显然是一种奢望,很多时候甚至必须要从头写自己的代码。但是阅读igraph和networkx这样成型了的函数库对熟悉算法和相关语言的技巧是很有用的。

      igraph(http://igraph.sourceforge.net/)是在处理复杂网络问题中用的比较多的C语言函数库,不过它也提供了R,python的接口。

      networkx(http://networkx.lanl.gov/)是用基于python的dictionary的一个复杂网络库。众所周知的是,python语言在对程序效率要求不是很苛刻的时候是构建程序的最佳选择一(对python不熟悉的图论研究者可以看看我在人人上的一篇日志(http://blog.renren.com/blog/bp/QmicNX45As),而用python语言写成的networkx充分利用了python中的dictionary的特性,将python的动态性发挥到了极致,研究networkx源代码对于研究算法和做相关的实验是我们的不二选择。但是对于规模很大的问题,性能上的要求需要我们去使用诸如igraph,BGL(boost graph library,不过基本已经停止开发)之类用C/C++写成的库。

igraph中图的数据结构
      igraph中基本的graph structure采用的是EdgeList,所以在igraph中自然而然的允许multiedge的存在,当然它也提供了Adjancency list(对某些算法,大部分算法接受的参数是edgelist)。数据结构igraph_t定义如下:

 
typedef struct igraph_s {
  igraph_integer_t n;
  igraph_bool_t directed;
  igraph_vector_t from;
  igraph_vector_t to;
  igraph_vector_t oi;
  igraph_vector_t ii;
  igraph_vector_t os;
  igraph_vector_t is;
  void *attr;
} igraph_t;

(注意igraph中顶点和边都是从0开始编号一直到总数减一)。其中n是图的顶点个数,directed标志是否是有向图。所有边的顶点存储在from和to两个向量(igraph_vector_t)中,oi[e]对应的是编号为e的边所对应的尾结点在from中的index,同样ii[e]对应于e的头节点在to中的index(也就是是说e 可以表示为 from[oi[e]] -> to[ii[e]])。所以from,to,oi,ii都是长度与边数相同的向量。os和is则和oi,ii相反,表示的是从顶点到边的映射,从顶点v出发的第一条边为 from[oi[os[v]]] -> to[ii[os[v]]],所以当os[v] == os[v + 1]时候就表示从该顶点没有出边。向量is同理。os,is都是长度为顶点数加一的向量。操作igraph_t的一些基本API如igraph_empty, igraph_adjacent等见于文档手册(btw,igraph的文档写的很全很好,有空应该研究一下它制作文档的技术)。

 

      因为采用的是edgelist的结构,所以增/减边(顶点)的操作在igraph中是相当耗费时间的。add和delete操作的时间复杂度基本上都是O(|V| + |E|)或者O(|V|)。(oops!)

 

      igraph实现了自己的一套数据结构诸如vector, heap,hashtable(一般的C程序库都是这么干的,C程序员总是重复制造轮子么。。。),因为C没有C++/JAVA中的泛型,一般都是采取void*指针或者宏的方式来实现泛型。igraph采用的是后者。大致看了一下,感觉收获还是很多的。igraph将类型无关的代码都抽象出来放在*pmt.h *pmt这样的文件模板里面。types.h和相关的C文件中则利用这些代码模板生成相应的声明和定义。一个典型的代码片段如下:

#define BASE_BOOL  
#include "igraph_pmt.h"  
#include "vector.pmt"  
#include "igraph_pmt_off.h"  
#undef BASE_BOOL 
#define BASE_BOOL
#include "igraph_pmt.h"
#include "vector.pmt"
#include "igraph_pmt_off.h"
#undef BASE_BOOL

 


其中vector.pmt定义的是类型无关的代码,igraph_pmt_off.h则小心翼翼的将宏清除出去(再一次感慨C++有模板真是太好了。。。)。这种手法还是有借鉴意义的(比起void*我更喜欢这样)。

      另外还学到了#error可以用来检测编译期间的错误(又一次证明我对C的了解还是太少太少。。。汗)。

      igraph的基本数据结构就写这么多,感兴趣的研究者可以去看API文档和相应的源码。算法留待下回分解,igraph中最出彩的部分就是它实现了相当一部分较新的复杂网络算法(包括网络流、图同构、匹配算法以及社团结构等)。

Networkx的数据结构
      得益于python语言的简洁明快,所以看Networkx的源码基本上是一览无余,这应该就是Knuth所说的Literate Programming吧。Networkx中图的数据结构主要有Graph(简单无向图), DiGraph(简单有向图), MultiGraph(允许有重边的无向图)和MultiDiGraph(允许有重边的有向图)。他们的实现都扎根于Python字典类的强大(Oreilly出版的《代码之美》一书中称Python的Dictionary类为全能战士,此话一点不错!)。关于Networkx的数据结构我这里就不赘述了,Python代码最好的解释了它自己。(再次向大家推荐Python编程语言! -_- )。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/rogerrecharad/archive/2010/11/07/5993723.aspx

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值