Dijkstra算法路径显示异常:仅输出终点及1步,求排查
Dijkstra算法路径仅显示终点的问题排查与修复
核心问题1:外层循环重复初始化状态,导致路径信息丢失
你的代码将dist、prev、q的初始化逻辑放在了外层while not finished循环内部,每次循环都会重置这些关键状态变量。第一次执行内层循环时可能已经正确计算出路径并填充了prev,但外层循环会再次执行初始化,将prev所有值设为None,最后重构路径时只能得到终点。
修复方式:
将状态初始化代码移到外层循环之外:
# 初始化状态变量,移到while循环前 dist = {} prev = {} q = list() for row in grid: for square in row: pos = square.get_pos() dist[square.get_pos()] = float("inf") prev[square.get_pos()] = None if square.state in [SquareState.EMPTY, SquareState.START, SquareState.END]: q.append(pos) dist[start_pos] = 0 finished = False while not finished: # 直接执行内层循环,不再重复初始化 found = False while q and not found: # ... 原内层循环逻辑 ...
核心问题2:找到终点后粗暴终止循环,可能影响路径完整性
原代码在检测到v == end_pos时直接清空队列并break,虽然能终止循环,但会中断当前节点的其他邻居处理,不符合Dijkstra算法的完整松弛流程(简单场景下可能不影响,但逻辑不严谨)。
修复方式:
用found标志控制循环终止:
found = False while q and not found: u = min(q, key=dist.__getitem__) q.remove(u) for v in _get_valid_neighbours(*u): alt = dist[u] + 1 if alt < dist[v]: dist[v] = alt prev[v] = u vr, vc = v grid[vr][vc].change_state(SquareState.VISITED) if v == end_pos: found = True break # ... 原绘制和事件处理代码 ...
问题3:路径重构未包含起点
当前_reconstruct_path函数的循环条件是while prev[current],当current到达起点时,由于prev[start_pos]为None,循环会停止,最终路径缺少起点。
修复方式:
修改循环逻辑,追踪到起点并加入路径:
def _reconstruct_path(): path = [] current = end_pos while current is not None: path.append(current) current = prev[current] path.reverse() return path
问题4:邻居筛选不必要排除起点
_get_valid_neighbours函数将SquareState.START加入排除列表,这会导致节点无法将起点视为有效邻居,虽然起点会被优先处理并移出队列,但这个限制没有必要,建议移除:
# 原判断条件 if grid[r][c].state not in [SquareState.VISITED, SquareState.WALL, SquareState.START]: # 修改为 if grid[r][c].state not in [SquareState.VISITED, SquareState.WALL]:
内容的提问来源于stack exchange,提问作者Benxsu
相关产品推荐
相关产品推荐

