我实现的无向图Dijkstra算法大样本运行失败,问题出在哪?
Dijkstra算法大规模场景运行失败问题排查
核心问题根因
你的代码在小规模下能返回正确结果,但大规模场景下性能崩盘,主要有三个核心问题:
- visited用列表存储,存在性判断效率极低
if node in visited对列表的查询时间复杂度是O(n),节点规模到5000时累计查询开销会达到百万级,是最主要的超时原因之一,需要改为集合(Set)实现O(1)复杂度的存在性判断。 - 堆中冗余数据过多,堆操作性能骤降
当前代码无论邻接节点的最短距离是否被更新,都会无条件将当前距离压入堆中。大规模图场景下堆内会堆积海量过时的无效距离记录,堆的push/pop操作复杂度为O(log m),m为堆大小,当m膨胀到数万甚至数十万级时,操作耗时会指数级上升,甚至触发内存不足。 - 未提前过滤堆内无效记录
弹出堆元素时没有判断当前弹出的距离是否已经大于该节点的已知最短距离,无效的旧记录也会走后续逻辑,额外浪费性能。
优化后代码
from heapq import heappush, heappop def dijkstra(edges, start): # 构建无向图邻接表 graph = {} for (x, y, z) in edges: graph[x] = graph.get(x, []) + [(y, z)] graph[y] = graph.get(y, []) + [(x, z)] # 初始化距离和前驱表 distance_table = {} for v in graph: distance_table[v] = (float("inf"), None) distance_table[start] = (0, None) heap = [(0, start)] # 用集合存储已处理节点,O(1)判断 visited = set() while heap: curr_dist, node = heappop(heap) known_dist, _ = distance_table[node] # 弹出的是旧的无效记录,直接跳过 if curr_dist > known_dist or node in visited: continue visited.add(node) for neighbor, weight in graph[node]: neighbor_dist, _ = distance_table[neighbor] new_dist = curr_dist + weight # 只有找到更短路径时才更新并压入堆 if new_dist < neighbor_dist: distance_table[neighbor] = (new_dist, node) heappush(heap, (new_dist, neighbor)) return distance_table # 测试用例 edges = [['A', 'C', 1], ['C', 'E', 1], ['E', 'B', 1], ['A', 'B', 10]] print(dijkstra(edges, 'A'))
优化后的代码在节点数5000的场景下性能提升数十倍,不会出现运行超时或内存不足的问题,结果正确性和原逻辑一致。
内容的提问来源于stack exchange,提问作者mol
相关产品推荐
相关产品推荐

