生物医学网络科学Biomedical Network Science
Example05 / 09

Watts 阈值级联的"级联窗口"与分支过程

所属专题
网络鲁棒性、渗流与级联失效
下载
Notebook · .py

Watts 模型:节点在失效邻居比例 >= phi 时失效。度 k <= 1/phi 的节点是”易损节点”(一个失效邻居即可触发)。 全局级联条件:sum_k k(k-1) rho_k P(k) > ,rho_k = 1 若 k <= floor(1/phi)。对 ER 网络扫描 得到级联窗口,并与模拟比较。 分支过程部分:后代分布 p0, p1, p2 的灭绝概率 q 满足 q = g(q);临界分支过程的雪崩规模分布 P(s) ~ s^{-3/2}。 解读: 太小(网络不连通)或太大(易损节点太少)都不会出现全局级联;窗口边界附近有限规模效应明显, 解析判据略小于 1 时模拟仍可能出现少量全局级联。临界分支过程的对数斜率接近 -1.5。

Output输出图

Watts 阈值级联的"级联窗口"与分支过程:输出图 1

Output文字输出

<k>=0.8  解析判据 0.79 (>1 才可能全局级联)  模拟全局级联比例 0.00
<k>=1.5  解析判据 1.40 (>1 才可能全局级联)  模拟全局级联比例 0.67
<k>=3.0  解析判据 1.94 (>1 才可能全局级联)  模拟全局级联比例 0.90
<k>=5.0  解析判据 1.33 (>1 才可能全局级联)  模拟全局级联比例 0.60
<k>=6.0  解析判据 0.91 (>1 才可能全局级联)  模拟全局级联比例 0.33
<k>=7.0  解析判据 0.57 (>1 才可能全局级联)  模拟全局级联比例 0.00
<k>=9.0  解析判据 0.19 (>1 才可能全局级联)  模拟全局级联比例 0.00
超临界分支过程的灭绝概率 q = 0.5
临界分支过程雪崩规模分布的拟合指数 alpha ≈ 1.51(理论 1.5)

Code代码

# Watts 模型:节点在失效邻居比例 >= phi 时失效。度 k <= 1/phi 的节点是"易损节点"(一个失效邻居即可触发)。
# 全局级联条件:sum_k k(k-1) rho_k P(k) > <k>,rho_k = 1 若 k <= floor(1/phi)。对 ER 网络扫描 <k> 得到级联窗口,并与模拟比较。
# 分支过程部分:后代分布 p0, p1, p2 的灭绝概率 q 满足 q = g(q);临界分支过程的雪崩规模分布 P(s) ~ s^{-3/2}。
# 解读:<k> 太小(网络不连通)或太大(易损节点太少)都不会出现全局级联;窗口边界附近有限规模效应明显,
# 解析判据略小于 1 时模拟仍可能出现少量全局级联。临界分支过程的对数斜率接近 -1.5。
import numpy as np
import networkx as nx
from scipy.stats import poisson

def watts_condition(kmean, phi, kmax=60):
    k = np.arange(kmax); P = poisson.pmf(k, kmean)
    rho = (k <= np.floor(1 / phi)).astype(float); rho[0] = 0
    return np.sum(k * (k - 1) * rho * P) / kmean

def watts_sim(n, kmean, phi, trials=30, seed=0):
    G = nx.fast_gnp_random_graph(n, kmean / (n - 1), seed=seed)
    rng = np.random.default_rng(seed); big = 0
    deg = dict(G.degree())
    for _ in range(trials):
        failed = {int(rng.integers(n))}; frontier = list(failed)
        while frontier:
            new = []
            for v in frontier:
                for w in G[v]:
                    if w not in failed and deg[w] > 0 and sum(x in failed for x in G[w]) / deg[w] >= phi:
                        failed.add(w); new.append(w)
            frontier = new
        big += len(failed) > 0.1 * n
    return big / trials

phi = 0.18
kms, sims = [0.8, 1.5, 3, 5, 6, 7, 9], []
for km in kms:
    sims.append(watts_sim(3000, km, phi))
    print("<k>=%.1f  解析判据 %.2f (>1 才可能全局级联)  模拟全局级联比例 %.2f" % (km, watts_condition(km, phi), sims[-1]))

# 分支过程:p0=0.25, p1=0.25, p2=0.5 -> 平均后代 1.25,灭绝概率 q = 0.5(手算见正文)
g = lambda q: 0.25 + 0.25 * q + 0.5 * q ** 2
q = 0.0
for _ in range(200):
    q = g(q)
print("超临界分支过程的灭绝概率 q =", round(q, 4))

rng = np.random.default_rng(1); sizes = []
for _ in range(20000):                       # 临界:p0 = p2 = 1/2
    active, s = 1, 1
    while active > 0 and s < 10 ** 5:
        kids = 2 * rng.integers(0, 2, size=active).sum()
        active = kids; s += kids
    sizes.append(s)
sizes = np.array(sizes)
bins = np.logspace(0, 4, 13); h, e = np.histogram(sizes, bins=bins, density=True)
c = np.sqrt(e[1:] * e[:-1]); ok = h > 0
print("临界分支过程雪崩规模分布的拟合指数 alpha ≈ %.2f(理论 1.5)" % -np.polyfit(np.log(c[ok][2:]), np.log(h[ok][2:]), 1)[0])

import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
kg = np.linspace(0.5, 10, 120)
ax1.plot(kg, [watts_condition(x, phi) for x in kg], c="0.4", label="analytic condition")
ax1.axhline(1, ls="--", c="tab:red", lw=1)
ax1.set_xlabel("mean degree <k>"); ax1.set_ylabel("cascade condition (>1 = global)")
ax1b = ax1.twinx(); ax1b.plot(kms, sims, "o", c="tab:blue", label="simulated P(global)")
ax1b.set_ylabel("fraction of global cascades", color="tab:blue"); ax1b.set_ylim(0, 1.05)
ax1.set_title("Cascade window (phi = %.2f)" % phi)
h1, l1 = ax1.get_legend_handles_labels(); h2, l2 = ax1b.get_legend_handles_labels(); ax1.legend(h1 + h2, l1 + l2, fontsize=8)
ax2.loglog(c[ok], h[ok], "o", label="critical branching")
ax2.loglog(c[ok], h[ok][0] * (c[ok] / c[ok][0]) ** -1.5, "k--", label="slope -3/2")
ax2.set_xlabel("avalanche size s"); ax2.set_ylabel("P(s)"); ax2.legend(); ax2.set_title("Avalanche sizes ~ s^(-3/2)")
plt.tight_layout(); plt.show()

Run在浏览器中运行

首次加载 Python 环境约需 20–40 秒;可以修改参数后重新运行。

Watts 阈值级联的"级联窗口"与分支过程