You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Networkx:如何按广度优先方式遍历有向图(DiGraph)的所有边?

解决NetworkX有向图中按广度优先顺序遍历所有边的问题

我明白你的困扰——bfs_edges确实只会返回每个节点第一次被发现时的那条边,完全忽略了节点的其他前驱边,这显然不符合你要遍历所有边的需求。既然你的图里所有节点都能从源节点0到达,我们可以换个思路来实现按BFS顺序遍历所有边。

方案1:按BFS节点顺序遍历所有出边

如果你的需求是从源节点0开始,先处理0的所有出边,再处理第一层节点的所有出边,以此类推,那可以先通过BFS获取节点的访问顺序,再逐个遍历每个节点的所有出边:

import networkx as nx

# 初始化你的有向图
G = nx.DiGraph()
# 添加你的边列表(示例边仅供参考)
edges = [(0, 1), (0, 2), (1, 3), (2, 3), (0, 3)]
G.add_edges_from(edges)

# 获取从0出发的BFS节点访问顺序
bfs_nodes = list(nx.bfs_tree(G, source=0).nodes())

# 按BFS顺序遍历所有出边并编辑属性
for node in bfs_nodes:
    for neighbor in G.neighbors(node):
        edge = (node, neighbor)
        # 这里可以编辑边的属性,比如设置weight为层级值
        G.edges[edge]['weight'] = nx.shortest_path_length(G, 0, node)
        print(f"已处理边: {edge}")

这个方法的核心是先拿到BFS的节点访问序列,再对每个节点遍历它的所有出边,保证边的处理顺序严格遵循BFS的层级逻辑。

方案2:按BFS节点顺序遍历所有入边

如果你的需求是按节点被BFS发现的顺序,处理该节点的所有入边(比如节点3被发现后,一次性处理(0,3)、(1,3)、(2,3)所有入边),那可以这样实现:

import networkx as nx

G = nx.DiGraph()
edges = [(0, 1), (0, 2), (1, 3), (2, 3), (0, 3)]
G.add_edges_from(edges)

# 获取BFS节点顺序,跳过源节点0(它没有前驱边)
bfs_nodes = list(nx.bfs_tree(G, source=0).nodes())[1:]

# 按BFS节点顺序遍历所有入边并编辑属性
for node in bfs_nodes:
    for predecessor in G.predecessors(node):
        edge = (predecessor, node)
        # 这里编辑边属性,比如标记为已处理
        G.edges[edge]['processed'] = True
        print(f"已处理边: {edge}")

这种方式会先处理第一层节点(1、2)的所有入边,再处理第二层节点3的所有入边,完全符合BFS的层级遍历顺序。

为什么bfs_edges不适用?

补充下背后的原因:nx.bfs_edges(G, source=0)的设计初衷是生成BFS树的边,它只会追踪每个节点第一次被访问时的路径,所以当节点有多个前驱时,只有第一条到达它的边会被返回,其他边都会被遗漏,这显然满足不了你遍历所有边的需求。

内容的提问来源于stack exchange,提问作者Clément F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:49:32