生物医学网络科学Biomedical Network Science
Example03 / 12

驱动节点比例与平均度、度异质性

所属专题
网络可控性与稳定性
下载
Notebook · .py

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

Output输出图

驱动节点比例与平均度、度异质性:输出图 1

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 秒;可以修改参数后重新运行。

驱动节点比例与平均度、度异质性