Example03 / 12
驱动节点比例与平均度、度异质性
比较 ER 有向网络与无标度有向网络(N=1000,静态模型,度指数 gamma=2.5)在不同平均度下的 驱动节点比例 n_D = N_D/N,并检查驱动节点的平均度是否低于全网平均度(驱动节点避开枢纽)。 解读:平均度越高 n_D 越低;同等平均度下无标度网络 n_D 更高;驱动节点的平均度低于全网平均度。
Output输出图

Output文字输出
<k>=1 n_D(ER) = 0.444 n_D(SF) = 0.606 <k>=2 n_D(ER) = 0.207 n_D(SF) = 0.438 <k>=3 n_D(ER) = 0.072 n_D(SF) = 0.331 <k>=4 n_D(ER) = 0.022 n_D(SF) = 0.228 <k>=6 n_D(ER) = 0.004 n_D(SF) = 0.105 SF 全网平均度 = 6.00,驱动节点平均度 = 2.30
Code代码
# 比较 ER 有向网络与无标度有向网络(N=1000,静态模型,度指数 gamma=2.5)在不同平均度下的
# 驱动节点比例 n_D = N_D/N,并检查驱动节点的平均度是否低于全网平均度(驱动节点避开枢纽)。
# 解读:平均度越高 n_D 越低;同等平均度下无标度网络 n_D 更高;驱动节点的平均度低于全网平均度。
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
def driver_nodes(G):
Bg = nx.Graph()
top = [("o", u) for u in G]
Bg.add_nodes_from(top); Bg.add_nodes_from([("i", v) for v in G])
Bg.add_edges_from((("o", u), ("i", v)) for u, v in G.edges())
M = nx.bipartite.hopcroft_karp_matching(Bg, top_nodes=top)
D = [v for v in G if ("i", v) not in M]
return D if D else [next(iter(G))]
def sf_directed(N, k_mean, gamma=2.5, seed=0):
"""静态模型:节点权重 w_i ∝ i^{-1/(gamma-1)},按权重分别抽取起点和终点。"""
rng = np.random.default_rng(seed)
w = np.arange(1, N + 1) ** (-1.0 / (gamma - 1)); w /= w.sum()
L = int(k_mean * N)
codes = np.array([], dtype=np.int64)
while codes.size < L: # 批量抽样,去掉自环和重边
u = rng.choice(N, 4 * L, p=w); v = rng.choice(N, 4 * L, p=w)
codes = np.concatenate([codes, (u * N + v)[u != v]])
_, idx = np.unique(codes, return_index=True)
codes = codes[np.sort(idx)]
G = nx.DiGraph(); G.add_nodes_from(range(N))
G.add_edges_from((int(c // N), int(c % N)) for c in codes[:L])
return G
N = 1000
ks = [1, 2, 3, 4, 6]
nd_er, nd_sf = [], []
for k in ks:
G_er = nx.gnm_random_graph(N, k * N, directed=True, seed=k)
G_sf = sf_directed(N, k, seed=k)
nd_er.append(len(driver_nodes(G_er)) / N)
nd_sf.append(len(driver_nodes(G_sf)) / N)
print("<k>=%d n_D(ER) = %.3f n_D(SF) = %.3f" % (k, nd_er[-1], nd_sf[-1]))
plt.plot(ks, nd_er, "o-", label="ER"); plt.plot(ks, nd_sf, "s-", label="SF (gamma=2.5)")
plt.xlabel("<k> (out-degree)"); plt.ylabel("n_D"); plt.legend(); plt.title("Driver node fraction")
plt.show()
G = sf_directed(N, 3, seed=9)
D = set(driver_nodes(G))
deg = dict(G.degree())
print("SF 全网平均度 = %.2f,驱动节点平均度 = %.2f" % (np.mean(list(deg.values())), np.mean([deg[v] for v in D])))Run在浏览器中运行
首次加载 Python 环境约需 20–40 秒;可以修改参数后重新运行。