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

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 = []

解决方案

  1. 排查generate_cell_equilibrium的副作用
    意外出现的numpy数组,大概率是depth_array被错误赋值导致的。代码中depth_array[successor] = depth_successor如果遇到非法的successor(比如数组而非单个节点ID),会触发numpy的切片赋值逻辑,后续某个操作可能把这个切片当成节点传入了predecessors_storage。

    • 先确认H.successors(predecessor)返回的所有节点都是合法类型(比如整数或元组),没有混入数组。
    • 检查generate_cell_equilibrium的逻辑,确保successor始终是单个节点,没有被意外转换为数组类型。
  2. 统一数据结构,避免隐式转换异常
    全程使用列表并手动去重,避免集合与列表混用可能引发的类型问题:

    # 保持顺序的去重方式
    successors_storage = list(dict.fromkeys(successors_storage))
    # 或用集合去重后转回列表
    successors_storage = list(set(successors_storage))
    predecessors_storage = successors_storage
    

    这样能确保predecessors_storage始终是列表类型,异常节点会更易被发现。

  3. 添加节点类型校验
    在处理后继节点前,加入校验逻辑过滤非法元素:

    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 15:15:14