Example10 / 11
多层网络的超邻接矩阵与超图的表示
- 两层多重网络:同一组 4 个神经元,层 1 为化学突触(有向),层 2 为电突触(无向), 层间耦合 ω 连接同一神经元的两个副本,拼成 8×8 的超邻接矩阵;对比“各层相加”的聚合矩阵。
- 超图:3 个蛋白复合物作为超边,用关联矩阵 H 表示;团展开得到加权图 H H^T(去掉对角元), 并展示两个不同的超图团展开后完全相同——团展开会丢失信息。
Output输出图

Output文字输出
超邻接矩阵(8×8,左上 = 化学突触层,右下 = 电突触层): [[0. 1. 0. 0. 0.5 0. 0. 0. ] [0. 0. 1. 0. 0. 0.5 0. 0. ] [0. 0. 0. 1. 0. 0. 0.5 0. ] [0. 0. 0. 0. 0. 0. 0. 0.5] [0.5 0. 0. 0. 0. 1. 0. 0. ] [0. 0.5 0. 0. 1. 0. 0. 1. ] [0. 0. 0.5 0. 0. 0. 0. 0. ] [0. 0. 0. 0.5 0. 1. 0. 0. ]] 聚合矩阵 A1 + A2(无法区分 n1–n2 之间是哪种突触): [[0. 2. 0. 0.] [1. 0. 1. 1.] [0. 0. 0. 1.] [0. 1. 0. 0.]] 超图关联矩阵 H(行 = 蛋白,列 = 复合物): [[1 0 0] [1 0 0] [1 1 0] [0 1 1] [0 0 1]] 团展开的加权邻接矩阵 H H^T(去对角): [[0 1 1 0 0] [1 0 1 0 0] [1 1 0 1 0] [0 0 1 0 1] [0 0 0 1 0]] “三个二元复合物”的团展开与“一个三元复合物”的团展开相同吗? True
Code代码
# (1) 两层多重网络:同一组 4 个神经元,层 1 为化学突触(有向),层 2 为电突触(无向),
# 层间耦合 ω 连接同一神经元的两个副本,拼成 8×8 的超邻接矩阵;对比“各层相加”的聚合矩阵。
# (2) 超图:3 个蛋白复合物作为超边,用关联矩阵 H 表示;团展开得到加权图 H H^T(去掉对角元),
# 并展示两个不同的超图团展开后完全相同——团展开会丢失信息。
import networkx as nx
import numpy as np
order = ["n1", "n2", "n3", "n4"]
chem = nx.DiGraph([("n1", "n2"), ("n2", "n3"), ("n3", "n4")])
gap = nx.Graph()
gap.add_nodes_from(order) # n3 没有电突触,但仍是该层的节点
gap.add_edges_from([("n1", "n2"), ("n2", "n4")])
A1 = nx.to_numpy_array(chem, nodelist=order)
A2 = nx.to_numpy_array(gap, nodelist=order)
omega = 0.5
I = np.eye(len(order))
supra = np.block([[A1, omega * I], [omega * I, A2]])
print("超邻接矩阵(8×8,左上 = 化学突触层,右下 = 电突触层):")
print(supra)
print("聚合矩阵 A1 + A2(无法区分 n1–n2 之间是哪种突触):")
print(A1 + A2)
# 超图:节点 P1..P5,超边 = 复合物
nodes = ["P1", "P2", "P3", "P4", "P5"]
complexes = {"C1": ["P1", "P2", "P3"], "C2": ["P3", "P4"], "C3": ["P4", "P5"]}
H = np.array([[1 if p in members else 0 for members in complexes.values()] for p in nodes])
print("超图关联矩阵 H(行 = 蛋白,列 = 复合物):")
print(H)
W = H @ H.T
np.fill_diagonal(W, 0)
print("团展开的加权邻接矩阵 H H^T(去对角):")
print(W)
# 另一个超图:P1–P2、P2–P3、P1–P3 是三个两两复合物,而不是一个三元复合物
H_alt = np.array([[1, 0, 1, 0, 0], [1, 1, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 1, 1], [0, 0, 0, 0, 1]])
W_alt = H_alt @ H_alt.T
np.fill_diagonal(W_alt, 0)
print("“三个二元复合物”的团展开与“一个三元复合物”的团展开相同吗?", np.array_equal(W, W_alt))
# 作图:左为超邻接矩阵(虚线分隔两层与层间耦合块),右为两个超图共同的团展开矩阵
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4.2))
im = ax1.imshow(supra, cmap="Blues", vmin=0, vmax=1)
ax1.axhline(3.5, color="#d6604d", ls="--"); ax1.axvline(3.5, color="#d6604d", ls="--")
labs = [n + "(chem)" for n in order] + [n + "(gap)" for n in order]
ax1.set_xticks(range(8)); ax1.set_xticklabels(labs, rotation=60, fontsize=7)
ax1.set_yticks(range(8)); ax1.set_yticklabels(labs, fontsize=7)
ax1.set_title("Supra-adjacency (omega = %.1f off-diagonal)" % omega, fontsize=10)
fig.colorbar(im, ax=ax1, fraction=0.046)
ax2.imshow(W, cmap="Oranges", vmin=0, vmax=2)
for i in range(5):
for j in range(5):
ax2.text(j, i, W[i, j], ha="center", va="center")
ax2.set_xticks(range(5)); ax2.set_xticklabels(nodes); ax2.set_yticks(range(5)); ax2.set_yticklabels(nodes)
ax2.set_title("Clique expansion H H^T: identical for both hypergraphs = %s" % np.array_equal(W, W_alt), fontsize=9)
plt.tight_layout(); plt.show()Run在浏览器中运行
首次加载 Python 环境约需 20–40 秒;可以修改参数后重新运行。