You need to enable JavaScript to run this app. Python实现带权图BFS最短路径适配带权邻接表报错如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Python实现带权图BFS最短路径适配带权邻接表报错如何解决

错误原因
  • 原有BFS代码默认适配无权图结构,邻接表中存储的直接是字符串类型的节点名
  • 你修改后的带权邻接表每个邻接项是[相邻节点名, 边权重]的列表,原有代码直接把这个列表加入了路径队列,下一轮遍历取path[-1]作为节点查询字典时,列表属于不可哈希类型,无法作为字典的key,因此抛出该报错。
适配带权图的代码修改方案

你只需要在遍历邻接项时拆分出节点名和边权重,将节点名加入路径队列即可,如果需要同步计算总通行距离,可以将队列改为存储「当前路径、总权重」的二元组,修改后的完整代码如下:

def BFS_SP(graph, start, goal):
    explored = []
    # 队列存储结构调整为 (当前路径列表, 路径累计总权重)
    queue = [([start], 0)]
    
    if start == goal:
        print("Same Node")
        return
    
    while queue:
        path, total_weight = queue.pop(0)
        node = path[-1]
        
        if node not in explored:
            neighbours = graph[node]
            for neighbour_item in neighbours:
                # 拆分邻接项的节点名和边权重
                neighbor_name, edge_weight = neighbour_item
                new_path = list(path)
                new_path.append(neighbor_name)
                new_total = total_weight + edge_weight
                queue.append((new_path, new_total))
                
                if neighbor_name == goal:
                    print("最短路径 = ", *new_path)
                    print("路径总通行距离 = ", new_total)
                    return
            explored.append(node)

    print("So sorry, but a connecting path doesn't exist :(")
    return

# 驱动代码直接使用你提供的带权邻接表即可
if __name__ == "__main__":
    graph = {
        'Arad':             [['Zerind', 75], ['Timisoara', 118], ['Sibiu', 140]],
        'Bucharest':        [['Urziceni', 85], ['Giurgiu', 90], ['Pitesti', 101], ['Fagaras', 211]],
        'Craiova':          [['Dobreta', 120], ['Pitesti', 138], ['Rimnicu Vilcea', 146]],
        'Dobreta':          [['Mehadia', 75], ['Craiova', 120]],
        'Eforie':           [['Hirsova', 86]],
        'Fagaras':          [['Sibiu', 99], ['Bucharest', 211]],
        'Giurgiu':          [['Bucharest', 90]],
        'Hirsova':          [['Eforie', 86], ['Urziceni', 98]],
        'Iasi':             [['Neamt', 87], ['Vaslui', 92]],
        'Lugoj':            [['Mehadia', 70], ['Timisoara', 111]],
        'Mehadia':          [['Lugoj', 70], ['Dobreta', 75]],
        'Neamt':            [['Iasi', 87]],
        'Oradea':           [['Zerind', 71], ['Sibiu', 151]],
        'Pitesti':          [['Rimnicu Vilcea', 97], ['Bucharest', 101], ['Craiova', 138]],
        'Rimnicu Vilcea':   [['Sibiu', 80], ['Pitesti', 97], ['Craiova', 146]],
        'Sibiu':            [['Rimnicu Vilcea', 80], ['Fagaras', 99], ['Arad', 140], ['Oradea', 151]],
        'Timisoara':        [['Lugoj', 111], ['Arad', 118]],
        'Urziceni':         [['Bucharest', 85], ['Hirsova', 98]],
        'Vaslui':           [['Iasi', 92], ['Urziceni', 142]],
        'Zerind':           [['Oradea', 71], ['Arad', 75]]
    }
    BFS_SP(graph, 'Arad', 'Bucharest')
后续学习方向

上面的修改仅解决了代码运行报错的问题,标准BFS逻辑是按边数优先级遍历,只能找到边数最少的路径,无法得到边权总和最小的最短路径,如果你的核心需求是计算带权图的最短路径,可按以下顺序学习相关算法:

  • 无负权边的带权图最短路径:Dijkstra算法
  • 存在负权边的带权图最短路径:Bellman-Ford算法
  • 需要结合启发信息优化搜索效率:A*算法

内容的提问来源于stack exchange,提问作者Meike Magdalena Büttner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 09:54:04