python结构模式图_NetworkX:Python图与网络模型基础
在《运筹学》课堂上,我们学习过图与网络,当时用到R语言下的igraph包来计算和展示结果。Python下也有类似甚至更好的库: NetworkX。
安装命令如下
conda install networkx
引入约定为
importnetworkxasnx
1 图的绘制
无向图
无向图由点和边构成,其绘制思路为:①新建空图→②添加点→③添加边。
新建空的无向图
G=nx.Graph()
以后所有的信息都添加在无向图G上。
添加点:addnode和add_nodes_from
# 添加一个点
G.add_node(1)# 点的名字叫1
G.add_node('a')# 点的名字叫a
# 添加一组点
G.add_nodes_from([2,3,4])
虽然还没有讲到怎么展示这张图,但你可能想看看自己已经画了啥;所以我们剧透一下:输入nx.draw(G)看看吧。
添加边:add_edge和add_edges_from
# 添加一条边
G.add_edge(1,2)# 在1、2之间添加边
G.add_edge(1,'a')# 在1、a之间添加边
# 添加一组边
G.add_edges_from([(2,3),(3,4,),('a',3)])
# 添加边时自动生成点
G.add_edge(3,'b')# 此前没有添加过b点
# 添加圈
G.add_cycle(['b','c','d'])
# 注意这些命令都有color参数,将来会用到
移除点或边使用remove_*系列方法。
展示图
NetworkX可以结合matpltlib库来展示图,因此需要载入plt:
importmatplotlib.pyplotasplt
最常用的展示命令是 networkx.draw(),所有参数都是可选的。
nx.draw()
简单介绍一些可选参数,如
ax:画纸名
nodecolor/edgecolor/font_color:点、边、字颜色
nodeshape/nodesize:点的形状和大小
style:边的形状(solid/dashed/dotted/dashdot)
alpha:点和边的透明度
with_labels:点是否显示标签
arrows/arrowstyle/arrowsize:有向图的箭头设定
我们并列展示默认和自定义结果:
fig=plt.figure(figsize=(20,5))
ax1=plt.subplot(121)
nx.draw(G,ax=ax1)
ax2=plt.subplot(122)
nx.draw(G,ax=ax2,node_color='pink',with_labels=True,node_size=500,node_shape='D',style='-.')
plt.draw()
另有 networkx.draw_networkx()函数,支持自定义点的位置(类型)。
有向图
有向图和无向图的差别仅仅在边是有方向的:
新建空的有向图
G=nx.DiGraph()# 注意差别
添加点:略
添加有向边
G.add_edge(1,2)
G.add_edges_from([(2,3),(2,4),(3,4),(4,3)])
nx.draw(G,ax=ax2,node_color='pink',with_labels=True,arrowstyle='fancy',edge_color='pink')
2 从图到网络:权的添加
方法一
add_weighted_edges_from方法能够接受(起点,终点,权重)作为元素的序列。推荐这种方法。
G=nx.DiGraph()
elist=[('a','b',5.0),('b','c',3.0),('a','c',1.0),('c','d',7.3)]
G.add_weighted_edges_from(elist)
方法二
add_edge方法可以添加weight参数。
G.add_edge(1,2,weight=5.5)
方法三
类索引方法,在修改权重时非常有用。
G[1][2]['weight']=5.5
G.edges[1,2]['weight']=5.5
添加权重标签
按照上述三个方法添加的边权重,将被记录在边属性下,我们可以通过G.edges(data=True)方法来查看:
G.edges(data=True)
特别注意参数data一定要为True,不指定data参数时默认只提取边的起点和终点。结果如下:
OutEdgeDataView([('a','b',{'weight':5.0}),('a','c',{'weight':1.0}),('b','c',{'weight':3.0}),('c','d',{'weight':7.3})])
关系已经很明确了,我们用元组u,v,w来解包,并将其放在键为边,值为权的字典中:
# 方法一:for循环
label={}
for(u,v,d)inG.edges(data=True):
label[(u,v)]=str(d['weight'])
# 方法二:字典推导式
label={(u,v):str(d['weight'])foru,v,dinG.edges(data=True)}
绘制权重标签
我们分4步来画图:点→边→点标签→边标签(顺序不重要)。因为要分4个图层来画,所以需要明确点的位置,不能用nx.draw()这种随性的方法。
首先定义点的位置pos:
pos=nx.spring_layout(G)
这表明我们使用Fruchterman-Reingold的力引导算法来画图,目的是减少边的交叉(推荐)。可选的pos还有circular_layout、kamada_kawai_layout、random_layout、rescale_layout、shell_layout和spectral_layout,点少的时候看不出来,点多就不一样了。
nx.draw_networkx_nodes(G,pos)
nx.draw_networkx_labels(G,pos)
nx.draw_networkx_edges(G,pos)
nx.draw_networkx_edge_labels(G,pos,label)# 关注这里
plt.axis('off')# 不显示坐标
plt.draw()
默认的标签是放在边的中间,可以用label_pos调节,这对双箭头的有向边很重要。
3 最短路
《运筹学》课程中,我们学习了Dijkstra算法;NetworkX提供了相应的命令:
dijkstra_predecessor_and_distance:给出某起点到所有点的最短路径和最短路程,结果也包含两部分,可以用元组解包提取;
dijkstra_path:给出从某起点到某终点的最短路径;
dijkstra_path_length:给出从某起点到某终点的最短路程。
构造一个有向图
G=nx.DiGraph()
elist=[(1,2,3),(1,3,2),(1,4,5),
(2,6,7),
(3,4,1),
(4,6,5),
(5,3,5),(5,4,3),(5,6,1)]
G.add_weighted_edges_from(elist)
求点1到点6的最短路。
展示这个有向图
pos=nx.circular_layout(G)
label={(u,v):str(d['weight'])foru,v,dinG.edges(data=True)}
nx.draw_networkx_nodes(G,pos,node_color='w',edgecolors='k')
nx.draw_networkx_nodes(G,pos,node_color='pink',edgecolors='k',nodelist=[1,6])
nx.draw_networkx_labels(G,pos,font_color='k')
nx.draw_networkx_edges(G,pos)
nx.draw_networkx_edge_labels(G,pos,label,label_pos=0.3)
plt.axis('off')
plt.draw()
Dijkstra算法求最短路
指定起点,不指定终点
pred,dist=nx.dijkstra_predecessor_and_distance(G,1)
print('到每个点的最短路的上一个点:',pred)
print('到每个点的最短路的路程:',dist)
结果:
到每个点的最短路的上一个点:{1:[],2:[1],3:[1],4:[3],6:[4]}
到每个点的最短路的路程:{1:0,3:2,2:3,4:3,6:8}
指定起点和终点
path=nx.dijkstra_path(G,1,6)
length=nx.dijkstra_path_length(G,1,6)
print('从点1到点6的最短路径是',path)
print('从点1到点6的最短路程是',length)
将最短路径画出来:
附代码:
pos=nx.circular_layout(G)
label={(u,v):str(d['weight'])foru,v,dinG.edges(data=True)}
nx.draw_networkx_nodes(G,pos,node_color='w',edgecolors='k')
nx.draw_networkx_nodes(G,pos,node_color='pink',edgecolors='k',nodelist=[1,6])
nx.draw_networkx_labels(G,pos,font_color='k')
nx.draw_networkx_edges(G,pos)
el=[(path[i],path[i+1])foriinrange(len(path)-1)]
nx.draw_networkx_edges(G,pos,edge_color='r',edgelist=el)
nx.draw_networkx_edge_labels(G,pos,label,label_pos=0.3)
plt.axis('off')
plt.draw()
4 最大流
掌握了最短路再来看最大流,就是很简单的事情了。
通过capacity参数为边添加最大容量;
使用 maximum_flow函数求解。
构造包含最大容量的有向图
elist=[(1,2,6),(1,4,6),(2,3,2),(2,5,3),(3,5,2),(3,6,2),(4,3,3),
(4,6,1),(4,7,2),(5,7,5),(6,7,4)]
G=nx.DiGraph()
foru,v,cinelist:
G.add_edge(u,v,capacity=c)
绘制这个图
pos=nx.circular_layout(G)
label={(u,v):str(d['capacity'])foru,v,dinG.edges(data=True)}
# 或者label = {(u,v):str(c) for u,v,c in elist}
nx.draw_networkx_nodes(G,pos,node_color='w',edgecolors='k')
nx.draw_networkx_nodes(G,pos,node_color='pink',edgecolors='k',nodelist=[1,7])
nx.draw_networkx_labels(G,pos,font_color='k')
nx.draw_networkx_edges(G,pos)
nx.draw_networkx_edge_labels(G,pos,label,label_pos=0.5)
plt.axis('off')
plt.draw()
图中边的标签表示最大容量(而非单位运价)。我们想求得从点1到点7的最大流。
计算最大流
flow_value,flow_dict=nx.maximum_flow(G,1,7)
通过提取flow_value,我们可以知道从点1到点7的最大流为10;
通过提取flow_dict,我们可以知道最大流情形下,每条边的实际流量:
{1:{2:5,4:5},
2:{3:2,5:3},
3:{5:2,6:2},
4:{3:2,6:1,7:2},
5:{7:5},
6:{7:3},
7:{}}
我们也可以通过 flow_dict[][]来确定特定边上的实际容量,如 flow_dict[1][4]表示边(1,4)上的实际流量为5。
5 结语
NetworkX是复杂网络计算库,能做的事情远不止最短路和最大流。手册在这里,进步靠自己:
https://networkx.github.io/documentation/stable/_downloads/networkx_reference.pdf
python结构模式图_NetworkX:Python图与网络模型基础相关推荐
- Python结构与列表
Python结构与列表 Python 程序的组织结构 顺序结构 对象的布尔值 选择结构 单分支结构 双分支结构 多分支结构 嵌套if 条件表达式 pass语句 知识点总结 列表 为什么需要列表 列表的 ...
- python 桑基图_流量结构分布图——桑基图(Sankey)
原标题:流量结构分布图--桑基图(Sankey) 桑基图作为相对复杂的图表种类,平时很少用到,不仅仅是因为它的引用场景相对狭窄,另一方面则是制作难度相对较大,门槛较高. 不过针对第一个问题,如果你能很 ...
- python结构体_Python对象初探
欢迎关注微信公众号--Python与统计分析,一起学习,一起交流. 相信所有学过Python的人都听过这样一句话:Python中,一切皆对象.一个整数是一个对象,产生这个整数的类int也是一个对象.函 ...
- python安装目录结构_1.5 python安装目录介绍《Python基础开发入门到精通》
第一章 Python的概述与环境安装 本章所讲内容: 1.1 Python介绍 1.2 Python2与Python3的比较 1.3 Python3的安装 1.4 Python环境变量配置 1.5 P ...
- LSTM结构理解与python实现
LSTM结构理解与python实现 上篇博客中提到,简单的RNN结构求解过程中易发生梯度消失或梯度爆炸问题,从而使得较长时间的序列依赖问题无法得到解决,其中一种越来越广泛使用的解决方法就是 Long ...
- 【游戏开发小技】TexturePacker生成的图集逆向切分成精灵小图(json | python | PIL | TextureUnPacker | 逆向 | 切图)
文章目录 一.前言 二.TexturePacker 1.特别说明 2.TexturePacker下载 3.准备精灵散图(小图) 4.使用TexturePacker打图集 5.json结构分析 三.图集 ...
- python无向带权图
无向无权图见另一篇文章<python无向无权图结构>,这篇讲无向带权图,并且给出一个地铁线路例子. # -*- coding: UTF-8 -*- #!/usr/bin/python#-- ...
- python怎么画高程三维网格图_matplotlib绘制等高线图
参考自Matplotlib Python 画图教程 (莫烦Python)(12)_演讲•公开课_科技_bilibili_哔哩哔哩 https://www.bilibili.com/video/av16 ...
- Python中的ULM类图
学会写类并不能说明你已经学会了面向对象的思想方法,因为还没能做到类与类之间的关联,也就是无法准确描绘现实世界.类图本身就是对现实世界的抽象,是一种编写程序的逻辑结构.以下是对类图知识点的梳理,以期能够 ...
最新文章
- [k8s] 第一章 十分钟带你理解Kubernetes核心概念
- 必读!TOP10生成对抗网络GAN论文(附链接)
- UAVStack的慢SQL数据库监控功能及其实现
- 【Python】疯狂的加速函数!
- html5中表格如何等分,纯css3饼图五等分
- react 判断图片是否加载完成_React中型项目的优化实践
- 【C语言】赋值运算中的类型转换
- 【资源】斯坦福李飞飞高徒Johnson博士论文: 组成式计算机视觉智能(附195页PDF)
- 什么是同步异步?阻塞非阻塞?
- 关于setInterval设置倒计时只执行一次,clearInterval停止
- 【Java-Web】初始化加载Serlvet工程后-HttpServlet报错
- Python str内部功能介绍
- windows7 配置iis技巧
- 免费申请微软云教育服务器,自助免费申请Office365教育版,免费5TOneDrive云盘详细教程...
- Kconfig配置文件
- matlab特定等值线,从Matlab轮廓函数中选择等值线
- PostgreSQL的json和jsonb比较
- 蓝奏云软件库源码分享下载(后端源码)
- 微信公众平台如何授权第三方平台,干货到!微信公众号怎样添加第三方平台及取消授权
- java中实现多态的机制是什么?
热门文章
- 计算机专业马来西亚,去马来西亚读计算机专业如何
- mysql数据类型内存_mysql 存储金额类型,用什么数据类型比较可靠,一般企业数据用什么数据类型?...
- 【入门篇】接口自动化测试
- 掩膜裁剪tif步骤_使用Arcgis掩膜剪裁工具剪裁全球气候数据为我国范围,并转换为ASC格式...
- 酒店前台html,酒店前台常用英语单词
- android 按钮列表,android – 如何使按钮看起来像列表
- python转json中文乱码_python 序列化成json 乱码问题的解决
- appinventor贪吃蛇制作步骤_旋转RGB制作指导
- 【3】测试用例设计-因果图
- java td背景色_jQuery:无法更改表格单元格的背景颜色