1.随机网络模型定义
随机网络与规则网络相对应,最为经典的随机网络模型是Erdös和Rényi研究的ER随机图模型,ER随机图模型有两种定义方式:
-
方式一:给定节点数N,固定连边数。每次随机选择一对节点并连边,重复M次。每次选择两个不同节点并且没有连接的节点对G(N,M),记作。算法如下:
首先给定N个节点和M条待连接边
-
随机选取一对没有边相连的不同节点,并在这对节点添加一条连边
-
重复上述步骤M次
代码实现如下:
import random
import networkx as nx
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['font.family'] = 'SimHei'
def GNL(N, L):
G = nx.Graph()
G.add_nodes_from(range(N))
nlist = list(G)
edge_count = 0
while edge_count < L:
# generate random edge,u,v
u = random.choice(nlist)
v = random.choice(nlist)
if u == v or G.has_edge(u, v):
continue
else:
G.add_edge(u, v)
edge_count += 1
return G
G = GNL(20, 60)
plt.figure(figsize=(12,4))
plt.subplot(131)
pos=nx.circular_layout(G)
G1 = GNL(20, 80)
G2 = GNL(20, 120)
nx.draw(G,pos, node_color="blue",node_size = 100)
plt.title("60条边")
plt.subplot(132)
nx.draw(G1,pos, node_color="blue",node_size = 100)
plt.title("80条边")
plt.subplot(133)
nx.draw(G2,pos, node_color="blue",node_size = 100)
plt.title("120条边")
plt.show()
实验结果如下:
-
方式二:给定N个节点,任意两个不同节点之间有一条连边概率固定为p,记作G(N,p),算法如下
初始化N个节点和固定概率p,
-
选择一对没有边相连的节点对
-
生成一个随机数r
[0,1]
-
若r<p,则在这两个节点之间添加一条边;否则不添加
-
重复上述步骤直至所有节点都被考虑一次。
-
特殊地,当p=0,则形成N个孤立的节点;p=1,则形成N阶全局耦合网络,对于无向网络,连边数为N(N-1)/2;当p
(0,1),连边数取值位于区间(0,N(N-1)/2)
实验代码如下:
import networkx as nx
import matplotlib.pyplot as plt
import random
import itertools
from matplotlib import rcParams
rcParams['font.family'] = 'SimHei'
def GNP(N, p):
edges = itertools.combinations(range(N), 2)
G = nx.Graph()
G.add_nodes_from(range(N))
for e in edges:
if random.random() < p:
G.add_edge(*e)
return G
G = GNP(20, 0.2)
G1 = GNP(20, 0.4)
G2 = GNP(20, 0.8)
plt.figure(figsize=(12,4))
pos=nx.circular_layout(G)
plt.subplot(131)
plt.title("概率为0.2")
nx.draw(G,pos, node_color="blue",node_size = 100)
plt.subplot(132)
plt.title("概率为0.4")
nx.draw(G1,pos, node_color="blue",node_size = 100)
plt.subplot(133)
plt.title("概率为0.8")
nx.draw(G2,pos, node_color="blue",node_size = 100)
plt.show()
实验结果如下:
也可以直接调用库函数来生成这两种网络
import networkx as nx
import matplotlib.pyplot as plt
# 可以直接调用库函数来生成这两种网络
n, m, p = 20,40,0.2
g1 = nx.gnm_random_graph(n, m)
g2 = nx.gnp_random_graph(n, p)
plt.figure(figsize=(8,4))
plt.subplot(121)
nx.draw(g1, pos=nx.circular_layout(g1), node_size=100, node_color="blue",with_labels=True)
plt.title("G(N,L)")
plt.subplot(122)
nx.draw(g2, pos=nx.circular_layout(g2), node_size=100, node_color="blue",with_labels=True)
plt.title("G(N,p)")
plt.show()
2.ER随机模型的度分布
代码实现:
# 导入库
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
import math
from scipy import stats
# 定义求度分布的函数
def get_pdf(G, kmin, kmax):
k = list(range(kmin, kmax + 1)) # 获取所有可能的度值
N = len(G.nodes())
Pk = []
for ki in k:
c = 0
for i in G.nodes():
if G.degree(i) == ki:
c += 1
Pk.append(c / N)
return k, Pk
samples = 100 # 统计平均次数
N = [100, 1000]
# 为了便于统计平均,指定区间[20,80]
kmin, kmax, avk = 20, 80, 50
s1 = np.zeros(kmax - kmin + 1)
s2 = np.zeros(kmax - kmin + 1)
for i in range(samples):
ER1 = nx.gnp_random_graph(N[0], avk / N[0])
x1, y1 = get_pdf(ER1, kmin, kmax)
ER2 = nx.gnp_random_graph(N[1], avk / N[1])
x2, y2 = get_pdf(ER2, kmin, kmax)
s1 += np.array(y1)
s2 += np.array(y2)
# 计算二项分布理论值
n = 100
p = 0.5
k = np.arange(20,81)
pk_b = stats.binom.pmf(k,n,p)
# 计算泊松分布理论值
pk_p = [np.exp(-avk)*(avk**ki)/math.factorial(ki) for ki in range(kmin,kmax+1)]
plt.figure(figsize=(6,4))
plt.plot(x1, s1/samples, 'ro', label='$N = 100$')
plt.plot(x2, s2/samples, 'bs', label='$N = 1000$')
plt.plot(x2, pk_b, 'g-', label='binomial')
plt.plot(x2, pk_p, 'r-', label='poisson')
plt.legend(loc=0)
plt.xlabel("$k$")
plt.ylabel("$p_k$")
plt.xlim([20,80])
plt.show()
实验结果: