对维基百科A*寻路算法伪代码判断逻辑的理解疑问
结论:维基百科的A*伪代码没有错误,你的理解偏差出在
gScore的初始化规则上 - 首先明确A*算法
gScore的标准初始化逻辑:
初始化阶段只有起点的gScore被设为0,其余所有节点的gScore默认值都是无穷大(工程实现中通常用一个远大于图中所有可能路径总长度的常量代替),并不是你推导中认为的distance(start, neighbor)。 - 回到你提到的首次迭代场景(current为起点):
此时遍历到的邻居节点neighbor还未被访问过,gScore[neighbor]仍是初始的无穷大值,而计算得到的tentative_gScore = distance(start, neighbor)是有限的正数,显然满足tentative_gScore < gScore[neighbor]的判断条件。判断成立后才会执行后续逻辑:把neighbor的gScore更新为这个计算值、记录父节点、将neighbor加入openSet待遍历队列。 - 这个判断在后续迭代中同样有实际作用:
当openSet中存在多个待遍历节点时,同一个neighbor可能先后被多个不同的current节点触达,此时计算的tentative_gScore代表「从起点出发,经过当前current节点到达neighbor」的路径总长度。如果这个值比已经记录的gScore[neighbor](即之前找到的到达neighbor的最短路径长度)更小,说明找到了更优的路径,判断成立后就会更新路径信息,保证最终得到的是最短路径。
你的推导漏洞:默认首次触达neighbor时,
gScore[neighbor]已经等于起点到neighbor的直接距离。实际上这个值是判断成立、执行更新逻辑之后才会被赋值的,初始状态下它是无穷大。
标准A*算法的gScore初始化伪代码参考:
// 初始化gScore字典/数组 gScore = 所有节点对应值初始为INF(无穷大) gScore[start] = 0 // 初始化开放集 openSet = 优先队列,初始仅加入起点start
内容的提问来源于stack exchange,提问作者Stack452378
相关产品推荐
相关产品推荐

