NetworkX用法之五——二分图(…

原文地址:NetworkX用法之五——二分图(转) 作者:zhengw789
二分图又称二部图,是图论中的一种特殊模型,它的顶点可分割为两个互不相交的子集,并且图中的每条边所关联的两个顶点分别属于这两个不同的顶点集。二分图在复杂网络分析中有很多应用,例如科学家合作网络(作者和论文)、商品网络(商品和购买者)、城市公交网络(线路和站点)等都可以用二分图来进行描述。NetworkX提供了一些基本的二分图建模与分析功能,下面对这些功能作一个简单的介绍。

一、建立二分图

建立二分图与建立普通的图方法比较类似,需要注意的是,边只能在不同类节点之间添加,同类节点之间不要添加边就可以。下面是一个简单的例子(本例中用1开头的编号表示项目节点,用2开头的编号表示参与者节点):

import networkx as nx
B = nx.Graph()
#添加一个项目101,它有3个参与者:201,202,203
B.add_edge(101,201)
B.add_edge(101,202)
B.add_edge(101,203)
#添加一个项目102,它有2个参与者:203,202,2034
B.add_edge(102,203)
B.add_edge(102,204)
…………………………

此外,
NetworkX还提供了多种二分图演化模型的建立方法,在这里把它们列出来供大家参考:
-- networkx.generators.classic.complete_bipartite_graph(n1, n2, create_using=None)-- networkx.generators.bipartite.bipartite_configuration_model (aseq, bseq, create_using=None, seed=None)
根据两个度序列建立一个二分图
-- networkx.generators.bipartite.bipartite_random_regular_graph(d, n, create_using=None, seed=None)
建立一个随机的规则二分图
-- networkx.generators.bipartite.bipartite_preferential_attachment_graph(aseq, p, create_using=None, seed=None)
建立一个优先连接的二分图
-- networkx.generators.bipartite.bipartite_havel_hakimi_graph(aseq, bseq, create_using=None)
根据两个度序列建立一个Havel-Hakimi模式的二分图(下面两个模型类似,我没有接触过这个模型,不太理解具体含义)
-- networkx.generators.bipartite.bipartite_reverse_havel_hakimi_graph(aseq, bseq, create_using=None)
-- networkx.generators.bipartite.bipartite_alternating_havel_hakimi_graph(aseq, bseq, create_using=None)

二、检测图的二分性

networkx.is_bipartite()方法可以检测一个图是否是二分图。例如对上边代码建立的二分图,nx.is_bipartite(B)返回的结果是True,而对一个随机图R = nx.random_graphs.gnp_random_graph(100,0.2),由于它不是二分图,nx.is_bipartite(R)返回的结果是False。

NetworkX并没有提供图的二分度计算方法,如果使用到这一功能需要自己编制代码。何大韧老师等编写的《复杂系统与复杂网络》一书的132页有二分度的计算公式,感兴趣的朋友可以自己实现这一程序。

此外,NetworkX还提供了对二分图节点进行着色的算法:networkx.bipartite_color(),它可以返回一个字典结构,分别为二分图中的两类节点赋予一个颜色值以示区别。例如对前面建立的二分图进行着色:print nx.bipartite_color(B),将返回结果 :{101: 1, 102: 1, 201: 0, 202: 0, 203: 0, 204: 0},项目节点被赋予颜色值1,参与者节点的颜色值是0。可以用这个值来检测节点类型,也可以用它来进行绘图(参看第4篇笔记《网络可视化》)。

三、二分图的投影

二分图可以通过向参与者节点投影或向项目节点投影转换为一个单分图(见下图),NetworkX提供的networkx.project(B, nodes)方法可以完成这一工作。它接受两个参数:一个是二分图B,另一个是投向的节点集合nodes。
[转载]NetworkX用法之五鈥斺敹分图(转)
二分图投影示意(向下投影)
对于节点集合的提取可以用networkx.bipartite_sets方法,它可以将一个二分图的两类节点提取为两个集合(X,Y),其中X是项目节点,Y是参与者节点。下面是一段示例代码,演示上述两个函数的用法:

(接第一节的代码之后)
NSet = nx.bipartite_sets(B)   #将二分图中的两类节点分别提取出来
Act = nx.project(B,NSet[0])     #向项目节点投影
Actor = nx.project(B,NSet[1]) #向参与者节点投影
print Act.edges() #输出 [(101, 102)]
print Actor.edges()   #输出 [(201, 202), (201, 203), (202, 203), (203, 204)]

四、通过派系提取构造二分图

对于一个存在派系(Clique)的图,可以通过提取派系结构生成一个二分图。NetworkX提供的networkx.make_clique_bipartite方法可以从图中查找派系,然后将一个派系作为一个项目节点并和该派系中的节点建立连接,从而构造一个二分图。它是二分图向参与者节点投影的逆过程,下边是一段示例代码:

(接第三节的代码之后)
G = nx.make_clique_bipartite(Actor)
print G.edges() #输出:[(201, -1), (202, -1), (203, -2), (203, -1), (204, -2)]

补充一点,NetworkX的派系提取算法据说效率很高,不过我没有做过这方面的东西,感兴趣的朋友可以去看它的源代码(见http://networkx.lanl.gov/reference/algorithms.clique.html)。

五、小结

本篇笔记介绍了用NetworkX进行二分图建模与分析的方法,到今天为止,我的《NetworkX学习笔记》就暂告一段落了。我目前的工作中只用到了这几篇笔记中所写的功能,以后如果有其他的心得体会我还会继续进行补充。希望这些文章对学习和研究复杂网络的朋友们能起到一点帮助作用,也欢迎各位留言批评、讨论。

最后,向NetworkX的三位开发者Aric Hagberg、Dan Schult 、Pieter Swart 以及许许多多的贡献者致敬*,感谢他们为我们提供了这样一个优秀的复杂网络分析工具!

根据三位开发者的建议,如果要在论文中引用NetworkX,请引用以下文献:
Aric A. Hagberg, Daniel A. Schult and Pieter J. Swart, “Exploring network structure, dynamics, and function using NetworkX”, in Proceedings of the 7th Python in Science Conference (SciPy2008), Gäel Varoquaux, Travis Vaught, and Jarrod Millman (Eds), (Pasadena, CA USA), pp. 11–15, Aug 2008


* 意外发现NetworkX的贡献者里还有复杂网络圈里的周涛、刘建国和汪秉宏老师,佩服啊!见https://networkx.lanl.gov/trac/changeset/681/networkx/trunk/networkx :“Graph A and B are from Tao Zhou, Jian-Guo Liu, Bing-Hong Wang: Comment on ``Scientific collaboration networks. II. Shortest paths, weighted networks, and centrality". http://arxiv.org/pdf/physics/0511084

建立一个完全二分图

你可能感兴趣的:(NetworkX用法之五——二分图(…)