BFS处理网格后继节点转set后出现意外array问题求助
问题:BFS遍历图时出现意外的numpy数组而非空列表
我现在用图结合BFS算法查找后继节点,因为网格特性,后继节点会重复,所以用集合去重。前几次迭代都正常,但最后一次迭代出现了意外的numpy数组,不是预期的空列表。我查资料知道循环时不该改数据结构,但改成全程用列表后问题还是存在。
原始代码
predecessors_storage = [source] successors_storage = [] total_dredged_sediment = 0 while (len(predecessors_storage) > 0): print('predecessors storage before loop', predecessors_storage) for predecessor in predecessors_storage: successors_storage += list(H.successors(predecessor)) successors_storage = set(successors_storage) for successor in successors_storage: depth_successor, dredged_sediment = generate_cell_equilibrium(H, successor, depth_array, dDepth) depth_array[successor] = depth_successor total_dredged_sediment += dredged_sediment predecessors_storage = successors_storage successors_storage = []
打印输出
predecessors storage before loop [3] predecessors storage before loop {9, 6} .... (this goes on for a while) predecessors storage before loop {59, 60} predecessors storage before loop {62} predecessors storage before loop [array([37, 39, 45, 47, 50, 51, 22, 54, 25, 26])] <- unexpected
可复现代码(单独文件运行正常)
import networkx as nx import numpy as np source = (0, 0) G = nx.grid_2d_graph(6, 6) bfs_edges_source = list(nx.edge_bfs(G, source)) H = nx.create_empty_copy(G, False).to_directed() H.add_edges_from(bfs_edges_source) predecessors_storage = [source] successors_storage = [] total_dredged_sediment = 0 while len(predecessors_storage) > 0: print(predecessors_storage) for predecessor in predecessors_storage: successors_storage += list(H.successors(predecessor)) successors_storage = set(successors_storage) predecessors_storage = successors_storage successors_storage = []
解决方案
排查
generate_cell_equilibrium的副作用
意外出现的numpy数组,大概率是depth_array被错误赋值导致的。代码中depth_array[successor] = depth_successor如果遇到非法的successor(比如数组而非单个节点ID),会触发numpy的切片赋值逻辑,后续某个操作可能把这个切片当成节点传入了predecessors_storage。- 先确认
H.successors(predecessor)返回的所有节点都是合法类型(比如整数或元组),没有混入数组。 - 检查
generate_cell_equilibrium的逻辑,确保successor始终是单个节点,没有被意外转换为数组类型。
- 先确认
统一数据结构,避免隐式转换异常
全程使用列表并手动去重,避免集合与列表混用可能引发的类型问题:# 保持顺序的去重方式 successors_storage = list(dict.fromkeys(successors_storage)) # 或用集合去重后转回列表 successors_storage = list(set(successors_storage)) predecessors_storage = successors_storage这样能确保
predecessors_storage始终是列表类型,异常节点会更易被发现。添加节点类型校验
在处理后继节点前,加入校验逻辑过滤非法元素:valid_successors = [] for succ in successors_storage: # 根据你的实际节点类型调整判断条件 if isinstance(succ, (int, tuple)): valid_successors.append(succ) else: print(f"发现非法节点类型: {succ},已跳过") successors_storage = valid_successors
内容的提问来源于stack exchange,提问作者Fab
相关产品推荐
相关产品推荐

