目录
一、前言
二、建模工具库Networkx的下载安装
三、规则图
四、ER随机图
五、WS小世界网络
六、BA无标度网络
七、补充
参考文献
一、前言
最近用Python实现了四种网络模型(规则图,ER随机图,WS小世界网络和BA无标度网络)的复现,具体内容为使用建模工具库Networkx实现网络模型的生成,平均度、最短路径长度、聚类系数等指标的计算,及度分布函数的计算和展示。
根据查询网上资料,我总结了一些方法,也产生了一些心得体会,呈现如下:
二、建模工具库Networkx的下载安装
Python中有一个库叫做NetworkX,其提供了4种常见网络的建模方法,分别是:规则图,ER随机图,WS小世界网络和BA无标度网络。下载该库后,生成网络模型就变得较为容易了。
直接pip install Networkx的话会特别慢,而且通常会失败,所以建议先把库下载下来,再在本地安装。
1. 下载地址:https://pypi.org/project/networkx/#files
2.放到自己指定的文件夹(随意)
3. cmd-输入指令安装:pip install 文件路径,如:
pip install D:\Study\networkX\networkx-2.8.8-py3-none-any.whl
三、规则图
1. 调用函数名:random_graphs.random_regular_graph(d, n)
2. 作用:生成一个包含n个节点、每个节点有d个邻居的规则图
3. 代码示例:
import networkx as nximport matplotlib.pyplot as plt# 生成了包含20个节点、每个节点有3个邻居的规则图G = nx.random_graphs.random_regular_graph(3, 10)# shell布局pos = nx.shell_layout(G)# 画出网络模型nx.draw(G, pos, with_labels = False, node_size = 30)# 获取各节点与相应度值的字典degree = dict(nx.degree(G))# 平均度为所有节点度之和除以总节点数print("平均度为:", sum(degree.values())/len(G))# 最短路径长度print("最短路径长度为:",nx.average_shortest_path_length(G))# 平均集类系数print("平均聚类系数为:",nx.average_clustering(G))# 获取度分布,返回所有位于区间[0, dmax]的度值的频数列表degreeDis = nx.degree_histogram(G)x = range(len(degreeDis))# 生成X轴序列,从1到最大度y = [z / float(sum(degreeDis)) for z in degreeDis]# 将频次转化为频率plt.figure(figsize=(5.8, 5.2), dpi=150) # 调整显示参数plt.rcParams['font.sans-serif'] = ['SimHei']# 用来正常显示中文标签plt.xlabel("Degree", size=14)# Degreeplt.ylabel("Frequency", size=14)# Frequencyplt.xticks(fontproperties='Times New Roman', size=13) # 字体样式plt.yticks(fontproperties='Times New Roman', size=13) # 字体样式plt.plot(x,y) # 折线图plt.show() # 显示图像
4. 输出结果:
四、ER随机图
1. 调用函数名:random_graphs.erdos_renyi_graph(n,p)
2. 作用:生成一个含有n个节点、以概率p连接的ER随机图
3. 代码示例:
import networkx as nximport matplotlib.pyplot as plt# 生成一个含有20个节点、以概率p = 0.2连接的ER随机图:G = nx.random_graphs.erdos_renyi_graph(20, 0.2)# shell布局pos = nx.shell_layout(G)# 画出网络模型nx.draw(G, pos, with_labels = False, node_size = 30)# 获取各节点与相应度值的字典degree = dict(nx.degree(G))# 平均度为所有节点度之和除以总节点数print("平均度为:", sum(degree.values())/len(G))# 最短路径长度print("最短路径长度为:",nx.average_shortest_path_length(G))# 平均集类系数print("平均聚类系数为:",nx.average_clustering(G))# 获取度分布,返回所有位于区间[0, dmax]的度值的频数列表degreeDis = nx.degree_histogram(G)x = range(len(degreeDis))# 生成X轴序列,从1到最大度y = [z / float(sum(degreeDis)) for z in degreeDis]# 将频次转化为频率plt.figure(figsize=(5.8, 5.2), dpi=150) # 调整显示参数plt.rcParams['font.sans-serif'] = ['SimHei']# 用来正常显示中文标签plt.xlabel("Degree", size=14)# Degreeplt.ylabel("Frequency", size=14)# Frequencyplt.xticks(fontproperties='Times New Roman', size=13) # 字体样式plt.yticks(fontproperties='Times New Roman', size=13) # 字体样式plt.plot(x,y) # 折线图plt.show() # 显示图像
4. 输出结果:
五、WS小世界网络
1. 调用函数名:random_graphs.watts_strogatz_graph(n, k, p)
2. 作用:生成一个含有n个节点、每个节点有k个邻居、以概率p随机化重连边的WS小世界网络
3. 代码示例:
import networkx as nximport matplotlib.pyplot as plt# 生成一个含有20个节点、每个节点有4个邻居、以概率p=0.3随机化重连边的WS小世界网络G = nx.random_graphs.watts_strogatz_graph(20, 4, 0.3)# circular布局pos = nx.circular_layout(G)nx.draw(G, pos, with_labels = False, node_size = 30)# 获取各节点与相应度值的字典degree = dict(nx.degree(G))# 平均度为所有节点度之和除以总节点数print("平均度为:", sum(degree.values())/len(G))# 最短路径长度print("最短路径长度为:",nx.average_shortest_path_length(G))# 平均集类系数print("平均聚类系数为:",nx.average_clustering(G))# 获取度分布,返回所有位于区间[0, dmax]的度值的频数列表degreeDis = nx.degree_histogram(G)x = range(len(degreeDis))# 生成X轴序列,从1到最大度y = [z / float(sum(degreeDis)) for z in degreeDis]# 将频次转化为频率plt.figure(figsize=(5.8, 5.2), dpi=150) # 调整显示参数plt.rcParams['font.sans-serif'] = ['SimHei']# 用来正常显示中文标签plt.xlabel("Degree", size=14)# Degreeplt.ylabel("Frequency", size=14)# Frequencyplt.xticks(fontproperties='Times New Roman', size=13) # 字体样式plt.yticks(fontproperties='Times New Roman', size=13) # 字体样式plt.plot(x,y) # 折线图plt.show() # 显示图像
4. 输出结果:
六、BA无标度网络
1. 调用函数名:random_graphs.barabasi_albert_graph(n, m)
2. 作用:生成一个含有n个节点、每次加入m条边的BA无标度网络
3. 代码示例:
import networkx as nximport matplotlib.pyplot as plt# 生成一个含有20个节点、每次加入1条边的BA无标度网络。G = nx.random_graphs.barabasi_albert_graph(20, 1)# spring 布局pos = nx.spring_layout(G)nx.draw(G, pos, with_labels = False, node_size = 30)# 获取各节点与相应度值的字典degree = dict(nx.degree(G))# 平均度为所有节点度之和除以总节点数print("平均度为:", sum(degree.values())/len(G))# 最短路径长度print("最短路径长度为:",nx.average_shortest_path_length(G))# 平均集类系数print("平均聚类系数为:",nx.average_clustering(G))# 获取度分布,返回所有位于区间[0, dmax]的度值的频数列表degreeDis = nx.degree_histogram(G)x = range(len(degreeDis))# 生成X轴序列,从1到最大度y = [z / float(sum(degreeDis)) for z in degreeDis]# 将频次转化为频率plt.figure(figsize=(5.8, 5.2), dpi=150) # 调整显示参数plt.rcParams['font.sans-serif'] = ['SimHei']# 用来正常显示中文标签plt.xlabel("Degree", size=14)# Degreeplt.ylabel("Frequency", size=14)# Frequencyplt.xticks(fontproperties='Times New Roman', size=13) # 字体样式plt.yticks(fontproperties='Times New Roman', size=13) # 字体样式#plt.loglog(x, y, '.') # 对数化坐标plt.plot(x,y) # 折线图plt.show() # 显示图像
4. 输出结果:
5. 幂律分布
另外,我还想测试一下BA网络的度分布是否真的呈现为幂律分布,因此尝试将函数random_graphs.barabasi_albert_graph(n, m)中的参数调整为100000,3;并将度分布对数化。因为数据量过大,网络模型画出来也会是乌黑黑一坨,因此干脆直接注释掉。
代码如下:
import networkx as nximport matplotlib.pyplot as plt# 生成一个含有100000个节点、每次加入3条边的BA无标度网络。G = nx.random_graphs.barabasi_albert_graph(100000, 3)# spring 布局#pos = nx.spring_layout(G)#nx.draw(G, pos, with_labels = False, node_size = 30)# 获取各节点与相应度值的字典#degree = dict(nx.degree(G))# 平均度为所有节点度之和除以总节点数#print("平均度为:", sum(degree.values())/len(G))# 最短路径长度#print("最短路径长度为:",nx.average_shortest_path_length(G))# 平均集类系数#print("平均聚类系数为:",nx.average_clustering(G))# 获取度分布,返回所有位于区间[0, dmax]的度值的频数列表degreeDis = nx.degree_histogram(G)x = range(len(degreeDis))# 生成X轴序列,从1到最大度y = [z / float(sum(degreeDis)) for z in degreeDis]# 将频次转化为频率plt.figure(figsize=(5.8, 5.2), dpi=150) # 调整显示参数plt.rcParams['font.sans-serif'] = ['SimHei']# 用来正常显示中文标签plt.xlabel("Degree", size=14)# Degreeplt.ylabel("Frequency", size=14)# Frequencyplt.xticks(fontproperties='Times New Roman', size=13) # 字体样式plt.yticks(fontproperties='Times New Roman', size=13) # 字体样式plt.loglog(x, y, '.') # 对数化坐标#plt.plot(x,y) # 折线图plt.show() # 显示图像
然后就出现了下面这样的报错:
根据查询资料发现报错原因是缺少名为“scipy”的包,因此尝试通过在cmd输入pip install scipy指令下载,但还是报错:
于是尝试更换下载源,还是报错:
最后通过这条指令才成功下载:
pip install scipy -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
输出结果如下:
七、补充
1. 运用样式
NetworkX提供了一系列样式参数,可以用来修饰和美化图形,达到我们想要的效果。常用的参数包括:
– node_size: 指定节点的尺寸大小(默认是300,单位未知,就是上图中那么大的点)
– node_color: 指定节点的颜色 (默认是红色,可以用字符串简单标识颜色,例如’r’为红色,’b’为绿色等,具体可查看手册)
– node_shape: 节点的形状(默认是圆形,用字符串’o’标识,具体可查看手册)
– alpha: 透明度 (默认是1.0,不透明,0为完全透明)
– width: 边的宽度 (默认为1.0)
– edge_color: 边的颜色(默认为黑色)
– style: 边的样式(默认为实现,可选: solid|dashed|dotted,dashdot)
– with_labels: 节点是否带标签(默认为True)
– font_size: 节点标签字体大小 (默认为12)
– font_color: 节点标签字体颜色(默认为黑色)
灵活运用上述参数,可以绘制不同样式的网络图形,例如:nx.draw(G,node_size = 30,with_labels = False) 是绘制节点尺寸为30、不带标签的网络图。
2. 运用布局
NetworkX在绘制网络图形方面提供了布局的功能,可以指定节点排列的形式。这些布局包括:
circular_layout:节点在一个圆环上均匀分布
random_layout:节点随机分布
shell_layout:节点在同心圆上分布
spring_layout: 用Fruchterman-Reingold算法排列节点
spectral_layout:根据图的拉普拉斯特征向量排列节点
布局用pos参数指定,例如:nx.draw(G,pos = nx.circular_layout(G))
参考文献
图论与复杂网络建模工具Networkx的四种网络模型_JYeeYao的博客-CSDN博客_random_graphs.watts_strogatz_graph(n, k, p)
复杂网络_JasonYangQ的博客-CSDN博客
复杂网络度分布(幂律分布)图Python_Morty Ma的博客-CSDN博客_网络度分布
pip install scipy warning: retryi”>解决pip安装包时出现 WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))_cicoa的博客-CSDN博客_c:\users\gaoying>pip install scipy warning: retryi