当组合权重小于节点权重时,放入队列的原因是什么?

时间:2019-08-05 20:57:57

标签: python algorithm dijkstra

正如您所看到的代码,首先在检查边缘顶点是否未访问但它是错误的之后,我将边缘顶点推入队列。 为了获得正确的答案,如果组合的值小于顶点权重,则必须在检查该值后才执行。 为什么会这样?

Please uninstall app for domain in Admin Console

1 个答案:

答案 0 :(得分:1)

我假设您已经在顶点类中定义了__lt__,以供heapq使用。每当将顶点的key属性的值更改时,将距离信息存储为属性可能会破坏您的最小堆不变式。而且在您的代码段中,我看不到任何可以重新建立不变量的东西。

说明::当to_vertex与以前在最小堆中的位置相同时,您可能已更改了其密钥以使其小于其父级或大于其任何子级。 。放入支票total_weight < edge.to_vertex.key时,只有前者会发生。

建议:改用最小的元组(<key>, <vertex>)堆。

以下内容还可以帮助解决代码中的其他一些问题:

  1. heapq.heappop(queue)返回current时,您首先必须检查它是否已被访问。如果不是,则将其标记为已访问,即current.visited = True,然后然后遍历出站边缘(即for edge in current.edge_list: ...)。我们检查是否已经访问过current,因为queue中可能存在该顶点的多个条目。

  2. 无论何时total_weight < edge.to_vertex.key,您都必须将edge.to_vertex推入您的最小堆中。这是因为您找到了通​​过current到达该顶点的更短方法。当然,您已经知道了。

  3. 请考虑代码中语句heapq.heappush(queue, edge.to_vertex)edge.to_vertex.key = total_weight的顺序。您正在之前to_vertex推入queue中,然后更新其权重。如果按照上面的建议使用最小的元组堆,此问题将消失。