生物医学网络科学Biomedical Network Science
Example09 / 15

k 核分解(逐层剥离)

所属专题
网络结构指标与随机图
下载
Notebook · .py

反复删除度 < k 的节点,直到剩余子图所有节点度 >= k,得到 k 核;节点所在最大 k 核的 k 值称为核数(coreness)。 这里用按当前度从小到大剥离的方法手工实现(Batagelj–Zaversnik 算法的朴素版本),与 nx.core_number 核对, 并打印每一层壳(k-shell)的节点数。 输出:空手道网络的最大核数为 4,最内核含 10 个节点(包括 0、33 等核心成员);手工结果与 NetworkX 一致。

Output输出图

k 核分解(逐层剥离):输出图 1

Output文字输出

与 NetworkX 一致: True
k-shell 1: 1 个节点
k-shell 2: 11 个节点
k-shell 3: 12 个节点
k-shell 4: 10 个节点
最内核(4 核)成员: [0, 1, 2, 3, 7, 8, 13, 30, 32, 33]

Code代码

# 反复删除度 < k 的节点,直到剩余子图所有节点度 >= k,得到 k 核;节点所在最大 k 核的 k 值称为核数(coreness)。
# 这里用按当前度从小到大剥离的方法手工实现(Batagelj–Zaversnik 算法的朴素版本),与 nx.core_number 核对,
# 并打印每一层壳(k-shell)的节点数。
# 输出:空手道网络的最大核数为 4,最内核含 10 个节点(包括 0、33 等核心成员);手工结果与 NetworkX 一致。
import networkx as nx

G = nx.karate_club_graph()


def core_number(G):
    H = G.copy()
    core, k = {}, 0
    while H.number_of_nodes() > 0:
        v, dv = min(H.degree(), key=lambda x: x[1])
        k = max(k, dv)                 # 核数单调不减
        core[v] = k
        H.remove_node(v)
    return core


mine = core_number(G)
print("与 NetworkX 一致:", mine == nx.core_number(G))
kmax = max(mine.values())
for k in range(1, kmax + 1):
    print("k-shell %d: %d 个节点" % (k, sum(1 for c in mine.values() if c == k)))
print("最内核(%d 核)成员:" % kmax, sorted(nx.k_core(G, kmax)))

# 作图:节点按核数着色,最内核节点加黑框
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(6.4, 4.2))
pos = nx.spring_layout(G, seed=4)
nx.draw_networkx_edges(G, pos, ax=ax, edge_color="0.7", alpha=0.4)
inner = set(nx.k_core(G, kmax))
nc = nx.draw_networkx_nodes(G, pos, ax=ax, node_color=[mine[v] for v in G], cmap=plt.get_cmap("Blues", kmax),
                            vmin=0.5, vmax=kmax + 0.5, node_size=[110 if v in inner else 60 for v in G],
                            edgecolors=["black" if v in inner else "0.6" for v in G])
fig.colorbar(nc, ax=ax, ticks=range(1, kmax + 1), label="coreness")
ax.set_title("k-core decomposition: %d nodes in the %d-core" % (len(inner), kmax), fontsize=10)
ax.axis("off"); plt.tight_layout(); plt.show()

Run在浏览器中运行

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

k 核分解(逐层剥离)