正如您所看到的代码,首先在检查边缘顶点是否未访问但它是错误的之后,我将边缘顶点推入队列。 为了获得正确的答案,如果组合的值小于顶点权重,则必须在检查该值后才执行。 为什么会这样?
Please uninstall app for domain in Admin Console
答案 0 :(得分:1)
我假设您已经在顶点类中定义了__lt__
,以供heapq使用。每当将顶点的key
属性的值更改时,将距离信息存储为属性可能会破坏您的最小堆不变式。而且在您的代码段中,我看不到任何可以重新建立不变量的东西。
说明::当to_vertex
与以前在最小堆中的位置相同时,您可能已更改了其密钥以使其小于其父级或大于其任何子级。 。放入支票total_weight < edge.to_vertex.key
时,只有前者会发生。
建议:改用最小的元组(<key>, <vertex>)
堆。
以下内容还可以帮助解决代码中的其他一些问题:
当heapq.heappop(queue)
返回current
时,您首先必须检查它是否已被访问。如果不是,则将其标记为已访问,即current.visited = True
,然后然后遍历出站边缘(即for edge in current.edge_list: ...
)。我们检查是否已经访问过current
,因为queue
中可能存在该顶点的多个条目。
无论何时total_weight < edge.to_vertex.key
,您都必须将edge.to_vertex
推入您的最小堆中。这是因为您找到了通过current
到达该顶点的更短方法。当然,您已经知道了。
请考虑代码中语句heapq.heappush(queue, edge.to_vertex)
和edge.to_vertex.key = total_weight
的顺序。您正在之前将to_vertex
推入queue
中,然后更新其权重。如果按照上面的建议使用最小的元组堆,此问题将消失。