NetworkX是一个用Python语言开发的图论与复杂网络建模工具,内置了常用的图与复杂网络分析算法,可以方便地进行复杂网络数据分析、仿真建模等工作。
我们可以通过在命令行提示符cmd(对于Windows系统)或者终端Terminal(对于Mac系统)使用下述命令安装NetworkX:
pip install networkx
如果已经是使用Anaconda作为编程集成环境,那电脑中已经装好该库了,无需再次安装。
一般我们在使用时会将其简写为nx
import networkx as nx
在绘图时我们往往也会结合Matplotlib库一起使用。 networkx 的一些常用函数举例如下:
Graph}()
:创建无向图;Graph}(A)
: 由邻接矩阵 A 创建无向图;DiGraph()
:创建有向图;DiGraph}(A)
: 由邻接矩阵 A 创建有向图;MultiGraph()
:创建多重无向图;MultiDigraph()
:创建多重有向图;add_edge()
:添加一条边;add_edges_from(List)
:从列表中添加多条边;add_node()
:添加一个顶点;add_nodes_from(List)
:添加顶点集合;dijkstra_path(G, source, target, weight='weight')
:求最短路径;dijkstra_path_length(G, source, target, weight='weight')
:求最短距离。可以根据图中两点之间是否有联系以及权重是多少构建赋权邻接矩阵(NetworkX中没有直接联系的点权重由0表示):
$$ \left[\begin{matrix}0 & 9 & 2 & 4 & 7\\9 & 0 & 3 & 4 & 0\\2 & 3 & 0 & 8 & 4\\4 & 4 & 8 & 0 & 6\\7 & 0 & 4 & 6 & 0\end{matrix}\right] $$import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
%matplotlib inline
a = np.array([[0., 9., 2., 4., 7.],
[9., 0., 3., 4., 0.],
[2., 3., 0., 8., 4.],
[4., 4., 8., 0., 6.],
[7., 0., 4., 6., 0.]])
a1 = pd.DataFrame(a,index=range(1,6),columns=range(1,6))
接下来根据邻接矩阵构建无向图
G = nx.from_numpy_array(a1)
G.edges(data=True) # 显示权重
绘制图像
pos=nx.shell_layout(G) #布局设置
nx.draw_networkx(G,pos,node_size=260)
w = nx.get_edge_attributes(G,'weight') # 获取权重
nx.draw_networkx_edge_labels(G,pos,font_size=12,edge_labels=w) #标注权重
plt.savefig('images/net0102.png')
plt.show()
图形的布局有五种设置:
circular_layout
:顶点在一个圆环上均匀分布;random_layout
:顶点随机分布;shell_layout
:顶点在同心圆上分布;spring_layout
: 用Fruchterman-Reingold算法排列顶点;spectral_layout
:根据图的拉普拉斯特征向量排列顶点。NetworkX中含有多种求最短路径的方法,如迪杰斯特拉(Dijkstra)算法,弗洛伊德(Floyd)算法等,我们可以同nx.shortest_path
和nx.shortest_path_length
来分别求最短路径及最短路径长度。
nx.shortest_path(G,5,2,weight='weight')
结果为[5,3,2]
.
nx.shortest_path_length(G,5,2,weight='weight')
结果为7
.
构造连通图最小生成树的算法有克鲁斯卡(Kruskal)算法和普利姆(Prim)算法。
tree_min = nx.minimum_spanning_tree(G,weight='weight')
pos=nx.shell_layout(G) #布局设置
nx.draw_networkx(tree_min,pos,node_size=260)
w = nx.get_edge_attributes(tree_min,'weight')
nx.draw_networkx_edge_labels(tree_min,pos,font_size=12,edge_labels=w) #标注权重
plt.savefig('images/net0103.png')
plt.show()
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd
%matplotlib inline
a = np.array([[0., 9., 2., 4., 7.],
[9., 0., 3., 4., 0.],
[2., 3., 0., 8., 4.],
[4., 4., 8., 0., 6.],
[7., 0., 4., 6., 0.]])
a1 = pd.DataFrame(a,index=range(1,6),columns=range(1,6))
G = nx.from_pandas_adjacency(a1)
G.edges(data=True)
EdgeDataView([(5, 4, {'weight': 6.0}), (5, 3, {'weight': 4.0}), (5, 1, {'weight': 7.0}), (4, 3, {'weight': 8.0}), (4, 2, {'weight': 4.0}), (4, 1, {'weight': 4.0}), (3, 2, {'weight': 3.0}), (3, 1, {'weight': 2.0}), (2, 1, {'weight': 9.0})])
pos=nx.shell_layout(G) #布局设置
nx.draw_networkx(G,pos,node_size=260)
w = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G,pos,font_size=12,edge_labels=w) #标注权重
plt.savefig('images/net0102.png')
plt.show()
nx.shortest_path(G,5,2,weight='weight')
[5, 3, 2]
nx.shortest_path_length(G,5,2,weight='weight')
7.0
pos=nx.shell_layout(G) #布局设置
nx.draw_networkx(G,pos,node_size=260)
w = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G,pos,font_size=12,edge_labels=w) #标注权重
p = nx.shortest_path(G,5,2,weight='weight')
path_edges=list(zip(p,p[1:]))
nx.draw_networkx_edges(G,pos,edgelist=path_edges,edge_color='r',width=3)
plt.savefig('images/net0104.png')
plt.show()
tree_min = nx.minimum_spanning_tree(G,weight='weight')
pos=nx.shell_layout(G) #布局设置
nx.draw_networkx(tree_min,pos,node_size=260)
w = nx.get_edge_attributes(tree_min,'weight')
nx.draw_networkx_edge_labels(tree_min,pos,font_size=12,edge_labels=w) #标注权重
plt.savefig('images/net0103.png')
plt.show()
a
array([[0., 9., 2., 4., 7.], [0., 0., 3., 4., 0.], [0., 0., 0., 8., 4.], [0., 0., 0., 0., 6.], [0., 0., 0., 0., 0.]])
a = np.array([[0. 9. 2. 4. 7.],[0. 0. 3. 4. 0.],[0. 0. 0. 8. 4.],[0. 0. 0. 0. 6.],[0. 0. 0. 0. 0.]])
File "<ipython-input-7-bee3c7d64f7d>", line 1 a = np.array([[0. 9. 2. 4. 7.],[0. 0. 3. 4. 0.],[0. 0. 0. 8. 4.],[0. 0. 0. 0. 6.],[0. 0. 0. 0. 0.]]) ^ SyntaxError: invalid syntax
b = np.triu(a).T+a
b.astype(int)
array([[0, 9, 2, 4, 7], [9, 0, 3, 4, 0], [2, 3, 0, 8, 4], [4, 4, 8, 0, 6], [7, 0, 4, 6, 0]])
import sympy as sp
print(sp.latex(sp.Matrix(b.astype(int))))
\left[\begin{matrix}0 & 9 & 2 & 4 & 7\\9 & 0 & 3 & 4 & 0\\2 & 3 & 0 & 8 & 4\\4 & 4 & 8 & 0 & 6\\7 & 0 & 4 & 6 & 0\end{matrix}\right]