许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  NetworkX学习与使用(3):路与圈

NetworkX学习与使用(3):路与圈

阅读数 6
点赞 0
article_banner

路与圈

前几个星期写论文去了,耽搁了更新。给自己一个小目标,每周坚持一更!

   为了保证实用性和逻辑性,接下来的更新内容会参考这本书的内容来学习networkx的使用。

大卫·伊斯利, 乔恩·克莱因伯格. 网络、群体与市场[M]. 清华大学出版社, 2011.

这本书在华文慕课上也有北大老师讲的非常nice的配套学习视频:人群与网络

实例构图

众所周知,互联网是从美国的ARPA 计算机网络  发展来的,1970年12月时的arpanet长这个样子:
arpanet1970

   利用networkx画出我们需要的graph:

import networkx as nx               #载入networkx包
import matplotlib.pyplot as plt     #用于画图
G = nx.Graph()                     #无向图
edges = [('UCSB','SRI'),('UCSB','UCLA'),
        ('SRI','UCLA'),('SRI','STAN'),('SRI','UTAH'),
        ('UCLA','STAN'),('UCLA','RAND'),
        ('UTAH','SDC'),('UTAH','MIT'),
        ('RAND','SDC'),('RAND','BBN'),
        ('MIT','BBN'),('MIT','LINC'),
        ('BBN','HARV'),
        ('LINC','CASE'),
        ('HARV','CARN'),
        ('CASE','CARN')]
G.add_edges_from(edges)

接下来是画图:

labels={}
for node in G.nodes():
    labels[node]=node

pos=nx.spring_layout(G)                     # 生成节点位置信息 
plt.rcParams['figure.figsize']= (6, 4)      # 设置画布大小
nx.draw_networkx_nodes(G,pos)               # 画节点
nx.draw_networkx_edges(G,pos)               # 画边
nx.draw_networkx_labels(G,pos,labels)       # 画标签 

plt.axis('off')                             # 去掉坐标刻度  

# 保存并显示图片
# plt.savefig("ARPA.png")
plt.show()

ARPA1970

   于是,我们成功的将一个简单的网络抽象成图,为接下来的分析做好了准备。

在用户手册的目录中,我们找到 算法  (Algorithms)下的最短路(shortest_path)和简单路(simple_path)。

最短路径

这里奉上最短路径相关的函数,从用户手册中直接截图出来的:
最短路径相关函数
寻找两点间的最短路径

print(nx.shortest_path(G, 'UCSB', 'SDC'))
out:
['UCSB', 'SRI', 'UTAH', 'SDC']

当然两点之间可能不止一条最短路径,所以我们可以输出所有最短路径:

print(list(nx.all_shortest_paths(G, 'UCSB', 'SDC')))
out:
[['UCSB', 'SRI', 'UTAH', 'SDC'], 
['UCSB', 'UCLA', 'RAND', 'SDC']]

最短路径的长度有四种用法,只输入图,输入图和源节点,输入图和目标节点和全都输入。

   仅输入图会返回各个节点到其他节点的最短距离的字典:

print(list(nx.shortest_path_length(G)))
out:
[('UCSB', {'UCSB': 0, 'SRI': 1, 'UCLA': 1, 'STAN': 2, 'UTAH': 2, 'RAND': 2, 'SDC': 3, 'MIT': 3, 'BBN': 3, 'LINC': 4, 'HARV': 4, 'CASE': 5, 'CARN': 5}), 
('SRI', {'SRI': 0, 'UCSB': 1, 'UCLA': 1, 'STAN': 1, 'UTAH': 1, 'RAND': 2, 'SDC': 2, 'MIT': 2, 'BBN': 3, 'LINC': 3, 'HARV': 4, 'CASE': 4, 'CARN': 5}), 
('UCLA', {'UCLA': 0, 'UCSB': 1, 'SRI': 1, 'STAN': 1, 'RAND': 1, 'UTAH': 2, 'SDC': 2, 'BBN': 2, 'MIT': 3, 'HARV': 3, 'LINC': 4, 'CARN': 4, 'CASE': 5}), 
('STAN', {'STAN': 0, 'SRI': 1, 'UCLA': 1, 'UCSB': 2, 'UTAH': 2, 'RAND': 2, 'SDC': 3, 'MIT': 3, 'BBN': 3, 'LINC': 4, 'HARV': 4, 'CASE': 5, 'CARN': 5}), 
('UTAH', {'UTAH': 0, 'SRI': 1, 'SDC': 1, 'MIT': 1, 'UCSB': 2, 'UCLA': 2, 'STAN': 2, 'RAND': 2, 'BBN': 2, 'LINC': 2, 'HARV': 3, 'CASE': 3, 'CARN': 4}), 
('RAND', {'RAND': 0, 'UCLA': 1, 'SDC': 1, 'BBN': 1, 'UCSB': 2, 'SRI': 2, 'STAN': 2, 'UTAH': 2, 'MIT': 2, 'HARV': 2, 'LINC': 3, 'CARN': 3, 'CASE': 4}), 
('SDC', {'SDC': 0, 'UTAH': 1, 'RAND': 1, 'SRI': 2, 'MIT': 2, 'UCLA': 2, 'BBN': 2, 'UCSB': 3, 'STAN': 3, 'LINC': 3, 'HARV': 3, 'CASE': 4, 'CARN': 4}), 
('MIT', {'MIT': 0, 'UTAH': 1, 'BBN': 1, 'LINC': 1, 'SRI': 2, 'SDC': 2, 'RAND': 2, 'HARV': 2, 'CASE': 2, 'UCSB': 3, 'UCLA': 3, 'STAN': 3, 'CARN': 3}), 
('BBN', {'BBN': 0, 'RAND': 1, 'MIT': 1, 'HARV': 1, 'UCLA': 2, 'SDC': 2, 'UTAH': 2, 'LINC': 2, 'CARN': 2, 'UCSB': 3, 'SRI': 3, 'STAN': 3, 'CASE': 3}), 
('LINC', {'LINC': 0, 'MIT': 1, 'CASE': 1, 'UTAH': 2, 'BBN': 2, 'CARN': 2, 'SRI': 3, 'SDC': 3, 'RAND': 3, 'HARV': 3, 'UCSB': 4, 'UCLA': 4, 'STAN': 4}), 
('HARV', {'HARV': 0, 'BBN': 1, 'CARN': 1, 'RAND': 2, 'MIT': 2, 'CASE': 2, 'UCLA': 3, 'SDC': 3, 'UTAH': 3, 'LINC': 3, 'UCSB': 4, 'SRI': 4, 'STAN': 4}), 
('CASE', {'CASE': 0, 'LINC': 1, 'CARN': 1, 'MIT': 2, 'HARV': 2, 'UTAH': 3, 'BBN': 3, 'SRI': 4, 'SDC': 4, 'RAND': 4, 'UCSB': 5, 'UCLA': 5, 'STAN': 5}), 
('CARN', {'CARN': 0, 'HARV': 1, 'CASE': 1, 'BBN': 2, 'LINC': 2, 'RAND': 3, 'MIT': 3, 'UCLA': 4, 'SDC': 4, 'UTAH': 4, 'UCSB': 5, 'SRI': 5, 'STAN': 5})]

仅输入图和源节点会返回源节点到其他节点的最短距离字典:

print(nx.shortest_path_length(G, source = 'UCSB'))
out:
{'UCSB': 0, 'SRI': 1, 'UCLA': 1, 'STAN': 2, 'UTAH': 2, 'RAND': 2, 'SDC': 3, 'MIT': 3, 'BBN': 3, 'LINC': 4, 'HARV': 4, 'CASE': 5, 'CARN': 5}

仅输入图和目标节点会返回其他节点到目标节点的最短距离字典:

print(nx.shortest_path_length(G, target= 'UCSB'))
out:
{'UCSB': 0, 'SRI': 1, 'UCLA': 1, 'STAN': 2, 'UTAH': 2, 'RAND': 2, 'SDC': 3, 'MIT': 3, 'BBN': 3, 'LINC': 4, 'HARV': 4, 'CASE': 5, 'CARN': 5}

这里结果和上面一样是因为这里计算的是无向图。

全都输入,等价于len(shortest_path()):

print(nx.shortest_path_length(G, source='UCSB', target = 'SDC'))
out:
3

平均最短路径,事实上就是将上面的所有节点对之间的最短距离求平均数:

print(nx.average_shortest_path_length(G))
out:
2.5641025641025643

求两点间是否有路可达

print(nx.has_path(G, 'UCSB', 'SDC'))
out:
True

简单路

所谓简单路,就是不走重复点的路。

   networkx中简单路仅有两个函数,求图中两点间的所有简单路径最短简单路径

print(list(nx.all_simple_paths(G, 'UCSB', 'SDC')))
out:
[['UCSB', 'SRI', 'UCLA', 'RAND', 'SDC'], 
['UCSB', 'SRI', 'UCLA', 'RAND', 'BBN', 'MIT', 'UTAH', 'SDC'], 
['UCSB', 'SRI', 'UCLA', 'RAND', 'BBN', 'HARV', 'CARN', 'CASE', 'LINC', 'MIT', 'UTAH', 'SDC'], 
['UCSB', 'SRI', 'STAN', 'UCLA', 'RAND', 'SDC'], 
['UCSB', 'SRI', 'STAN', 'UCLA', 'RAND', 'BBN', 'MIT', 'UTAH', 'SDC'], ['UCSB', 'SRI', 'STAN', 'UCLA', 'RAND', 'BBN', 'HARV', 'CARN', 'CASE', 'LINC', 'MIT', 'UTAH', 'SDC'], 
['UCSB', 'SRI', 'UTAH', 'SDC'], 
['UCSB', 'SRI', 'UTAH', 'MIT', 'BBN', 'RAND', 'SDC'], 
['UCSB', 'SRI', 'UTAH', 'MIT', 'LINC', 'CASE', 'CARN', 'HARV', 'BBN', 'RAND', 'SDC'], 
['UCSB', 'UCLA', 'SRI', 'UTAH', 'SDC'],
 ['UCSB', 'UCLA', 'SRI', 'UTAH', 'MIT', 'BBN', 'RAND', 'SDC'], 
 ['UCSB', 'UCLA', 'SRI', 'UTAH', 'MIT', 'LINC', 'CASE', 'CARN', 'HARV', 'BBN', 'RAND', 'SDC'], 
 ['UCSB', 'UCLA', 'STAN', 'SRI', 'UTAH', 'SDC'], 
 ['UCSB', 'UCLA', 'STAN', 'SRI', 'UTAH', 'MIT', 'BBN', 'RAND', 'SDC'], ['UCSB', 'UCLA', 'STAN', 'SRI', 'UTAH', 'MIT', 'LINC', 'CASE', 'CARN', 'HARV', 'BBN', 'RAND', 'SDC'], 
 ['UCSB', 'UCLA', 'RAND', 'SDC'], 
 ['UCSB', 'UCLA', 'RAND', 'BBN', 'MIT', 'UTAH', 'SDC'], 
 ['UCSB', 'UCLA', 'RAND', 'BBN', 'HARV', 'CARN', 'CASE', 'LINC', 'MIT', 'UTAH', 'SDC']]

最短简单路径的返回其实和所有简单路径的内容一样,但是得到的答案根据路径的长度,由短到长进行排序。

print(list(nx.shortest_simple_paths(G, 'UCSB', 'SDC')))
out:
[['UCSB', 'SRI', 'UTAH', 'SDC'], 
['UCSB', 'UCLA', 'RAND', 'SDC'],
['UCSB', 'SRI', 'UCLA', 'RAND', 'SDC'], 
['UCSB', 'UCLA', 'SRI', 'UTAH', 'SDC'],
['UCSB', 'SRI', 'STAN', 'UCLA', 'RAND', 'SDC'], 
['UCSB', 'UCLA', 'STAN', 'SRI', 'UTAH', 'SDC'], 
['UCSB', 'SRI', 'UTAH', 'MIT', 'BBN', 'RAND', 'SDC'],
['UCSB', 'UCLA', 'RAND', 'BBN', 'MIT', 'UTAH', 'SDC'],
['UCSB', 'SRI', 'UCLA', 'RAND', 'BBN', 'MIT', 'UTAH', 'SDC'],
['UCSB', 'UCLA', 'SRI', 'UTAH', 'MIT', 'BBN', 'RAND', 'SDC'],
['UCSB', 'SRI', 'STAN', 'UCLA', 'RAND', 'BBN', 'MIT', 'UTAH', 'SDC'],
['UCSB', 'UCLA', 'STAN', 'SRI', 'UTAH', 'MIT', 'BBN', 'RAND', 'SDC'],
['UCSB', 'SRI', 'UTAH', 'MIT', 'LINC', 'CASE', 'CARN', 'HARV', 'BBN', 'RAND', 'SDC'],
['UCSB', 'UCLA', 'RAND', 'BBN', 'HARV', 'CARN', 'CASE', 'LINC', 'MIT', 'UTAH', 'SDC'],
['UCSB', 'SRI', 'UCLA', 'RAND', 'BBN', 'HARV', 'CARN', 'CASE', 'LINC', 'MIT', 'UTAH', 'SDC'],
['UCSB', 'UCLA', 'SRI', 'UTAH', 'MIT', 'LINC', 'CASE', 'CARN', 'HARV', 'BBN', 'RAND', 'SDC'],
['UCSB', 'SRI', 'STAN', 'UCLA', 'RAND', 'BBN', 'HARV', 'CARN', 'CASE', 'LINC', 'MIT', 'UTAH', 'SDC'],
['UCSB', 'UCLA', 'STAN', 'SRI', 'UTAH', 'MIT', 'LINC', 'CASE', 'CARN', 'HARV', 'BBN', 'RAND', 'SDC']]

圈(环)

圈的简单定义为,长度大于三且起点与终点相同的路。

   networkx中与圈相关的函数:
圈函数
首先是求图中所有圈的基:

   先看networkx中关于圈的基给出的解释:A basis for cycles of a network is a minimal collection of cycles such that any cycle in the network can be written as a sum of cycles in the basis. Here summation of cycles is defined as “exclusive or” of the edges. Cycle bases are useful, e.g. when deriving equations for electric circuits using Kirchhoff’s Laws.

   网络圈的基是圈的最小 集合  ,这样网络中的任何圈都可以写成基中圈的和。这里圈的总和被定义为边的“异或”。圈基是有用的,例如,当使用基尔霍夫定律推导电路方程时。

nx.cycle_basis(G)
out:
[['BBN', 'HARV', 'CARN', 'CASE', 'LINC', 'MIT'],
 ['UTAH', 'SDC', 'RAND', 'BBN', 'MIT'],
 ['SRI', 'STAN', 'UCLA'],
 ['UCSB', 'SRI', 'UCLA'],
 ['UTAH', 'SRI', 'UCLA', 'RAND', 'BBN', 'MIT']]

第二个函数是针对有向图的,这里就不做展示了。

find_cycle()函数根据给定的源节点返回按照深度优先遍历找到的第一个圈,如果是有向图还能通过选择orientation参数来控制深度遍历的方向。

nx.find_cycle(G,'UCSB')
out:
[('UCSB', 'SRI'), ('SRI', 'UCLA'), ('UCLA', 'UCSB')]

完整代码 资源

networkx学习(3)

参考

networkx官网地址:https://networkx.org/

免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空