为什么 Dijkstra 算法使用减键?

编程入门 行业动态 更新时间:2024-10-19 15:44:22
本文介绍了为什么 Dijkstra 算法使用减键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

教给我的 Dijkstra 算法如下

Dijkstra's algorithm was taught to me was as follows

while pqueue is not empty: distance, node = pqueue.delete_min() if node has been visited: continue else: mark node as visited if node == target: break for each neighbor of node: pqueue.insert(distance + distance_to_neighbor, neighbor)

但我一直在阅读有关该算法的一些资料,我看到很多版本都使用减少键而不是插入.

But I've been doing some reading regarding the algorithm, and a lot of versions I see use decrease-key as opposed to insert.

这是为什么,这两种方法有什么区别?

Why is this, and what are the differences between the two approaches?

推荐答案

使用decrease-key而不是重新插入节点的原因是为了保持优先队列中的节点数量较少,从而保持优先队列出队的总数小且每个优先级队列平衡的成本低.

The reason for using decrease-key rather than reinserting nodes is to keep the number of nodes in the priority queue small, thus keeping the total number of priority queue dequeues small and the cost of each priority queue balance low.

在 Dijkstra 算法的一种实现中,该算法将具有新优先级的节点重新插入优先级队列中,图中的 m 条边中的每条边都将一个节点添加到优先级队列中.这意味着优先级队列上有 m 个入队操作和 m 个出队操作,总运行时间为 O(m Te + m Td),其中 Te 是进入优先队列所需的时间,Td 是从优先队列出队所需的时间.

In an implementation of Dijkstra's algorithm that reinserts nodes into the priority queue with their new priorities, one node is added to the priority queue for each of the m edges in the graph. This means that there are m enqueue operations and m dequeue operations on the priority queue, giving a total runtime of O(m Te + m Td), where Te is the time required to enqueue into the priority queue and Td is the time required to dequeue from the priority queue.

在支持递减键的 Dijkstra 算法的实现中,保存节点的优先级队列从其中的 n 个节点开始,并且在算法的每一步中删除一个节点.这意味着堆出队的总数是 n.每个节点将有可能对每条边调用一次减少键,因此完成的减少键总数最多为 m.这给出了 (n Te + n Td + m Tk) 的运行时间,其中 Tk是调用reduce-key所需的时间.

In an implementation of Dijkstra's algorithm that supports decrease-key, the priority queue holding the nodes begins with n nodes in it and on each step of the algorithm removes one node. This means that the total number of heap dequeues is n. Each node will have decrease-key called on it potentially once for each edge leading into it, so the total number of decrease-keys done is at most m. This gives a runtime of (n Te + n Td + m Tk), where Tk is the time required to call decrease-key.

那么这对运行时有什么影响?这取决于您使用的优先级队列.这是一个快速表格,显示了不同的优先级队列和不同 Dijkstra 算法实现的整体运行时间:

So what effect does this have on the runtime? That depends on what priority queue you use. Here's a quick table that shows off different priority queues and the overall runtimes of the different Dijkstra's algorithm implementations:

Queue | T_e | T_d | T_k | w/o Dec-Key | w/Dec-Key ---------------+--------+--------+--------+-------------+--------------- Binary Heap |O(log N)|O(log N)|O(log N)| O(M log N) | O(M log N) Binomial Heap |O(log N)|O(log N)|O(log N)| O(M log N) | O(M log N) Fibonacci Heap | O(1) |O(log N)| O(1) | O(M log N) | O(M + N log N)

如您所见,对于大多数类型的优先级队列,渐近运行时确实没有区别,并且减少键版本不太可能做得更好.但是,如果您使用优先队列的 斐波那契堆 实现,那么 Dijkstra 的算法确实会渐近使用减少键时更有效.

As you can see, with most types of priority queues, there really isn't a difference in the asymptotic runtime, and the decrease-key version isn't likely to do much better. However, if you use a Fibonacci heap implementation of the priority queue, then indeed Dijkstra's algorithm will be asymptotically more efficient when using decrease-key.

简而言之,如果您继续进行入队和出队,使用减少键,加上良好的优先级队列,可以将 Dijkstra 的渐进运行时间降低到超出可能的范围.

In short, using decrease-key, plus a good priority queue, can drop the asymptotic runtime of Dijkstra's beyond what's possible if you keep doing enqueues and dequeues.

除此之外,一些更高级的算法,例如 Gabow 的最短路径算法,使用 Dijkstra 的算法作为子程序,并严重依赖于减少键的实现.他们利用这样一个事实,如果你提前知道有效距离的范围,你可以基于这个事实构建一个超级高效的优先级队列.

Besides this point, some more advanced algorithms, such as Gabow's Shortest Paths Algorithm, use Dijkstra's algorithm as a subroutine and rely heavily on the decrease-key implementation. They use the fact that if you know the range of valid distances in advance, you can build a super efficient priority queue based on that fact.

希望这有帮助!

更多推荐

为什么 Dijkstra 算法使用减键?

本文发布于:2023-11-29 16:53:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1647006.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:算法   Dijkstra

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!