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

用广度优先搜索(BFS)求最短路径距离

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

用队列实现 BFS,求从源点 0 到所有节点的距离,并与 NetworkX 的结果对比; 按距离把节点分层输出,可以看到 BFS “一层一层”向外扩散。 最后计算整个网络的直径与平均路径长度(空手道网络是连通的,可直接计算)。 输出:自己的结果与 NetworkX 完全一致;直径为 5,平均路径长度约 2.41。

Output输出图

用广度优先搜索(BFS)求最短路径距离:输出图 1

Output文字输出

与 NetworkX 一致吗? True
距离 0 的节点: [0]
距离 1 的节点: [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 17, 19, 21, 31]
距离 2 的节点: [9, 16, 24, 25, 27, 28, 30, 32, 33]
距离 3 的节点: [14, 15, 18, 20, 22, 23, 26, 29]
直径 = 5 ,平均路径长度 = 2.408

Code代码

# 用队列实现 BFS,求从源点 0 到所有节点的距离,并与 NetworkX 的结果对比;
# 按距离把节点分层输出,可以看到 BFS “一层一层”向外扩散。
# 最后计算整个网络的直径与平均路径长度(空手道网络是连通的,可直接计算)。
# 输出:自己的结果与 NetworkX 完全一致;直径为 5,平均路径长度约 2.41。
import networkx as nx
from collections import deque

G = nx.karate_club_graph()


def bfs_distances(G, source):
    dist = {source: 0}
    queue = deque([source])
    while queue:
        v = queue.popleft()
        for u in G.neighbors(v):
            if u not in dist:
                dist[u] = dist[v] + 1
                queue.append(u)
    return dist


my = bfs_distances(G, 0)
ref = nx.single_source_shortest_path_length(G, 0)
print("与 NetworkX 一致吗?", my == dict(ref))
layers = {}
for node, d in my.items():
    layers.setdefault(d, []).append(node)
for d in sorted(layers):
    print("距离 %d 的节点: %s" % (d, sorted(layers[d])))
print("直径 =", nx.diameter(G), ",平均路径长度 = %.3f" % nx.average_shortest_path_length(G))

# 作图:节点按到源点 0 的 BFS 距离着色,可见“一层一层”向外扩散
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)
nc = nx.draw_networkx_nodes(G, pos, ax=ax, node_color=[my[v] for v in G], cmap=plt.get_cmap("viridis_r", max(my.values()) + 1), vmin=-0.5, vmax=max(my.values()) + 0.5,
                            node_size=[200 if v == 0 else 90 for v in G], edgecolors="0.3", linewidths=0.5)
fig.colorbar(nc, ax=ax, ticks=range(max(my.values()) + 1), label="BFS distance from node 0")
ax.set_title("BFS layers from node 0 (diameter = %d)" % nx.diameter(G))
ax.axis("off"); plt.tight_layout(); plt.show()

Run在浏览器中运行

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

用广度优先搜索(BFS)求最短路径距离