繁体   English   中英

为什么 Dikstra 算法运行在 O(V + E log V) 而不是 O(V ^ 2)?

[英]Why Does The Dikstra Algorithm Run In O(V + E log V) Instead Of O(V ^ 2)?

其中V是顶点数,E 是边数,在最坏的情况下,所有节点都是连接的,并且在每个节点上,您会查看所有其他节点。 那不就是O(V ^ 2)吗? 我查了一下,发现其实是O(V + E log V) ,但是没有解释。

不,根据此处,Dijkstra 使用斐波那契堆作为优先级队列的最佳实现以O(|E|+|V|*log|V|) 请记住,在密集图中, |E| O(|v|^2)O(|E|+|V|*log|V|)变得等于O(|V|^2) ,这是算法的最坏情况,但在任何情况下这些情况下它在O(|V|+|E|log|V|)

您的分析忽略了优先队列的成本。 不过,你也不是完全错了。

它需要 O(|E|) 次减少键操作,因为您访问的几乎每条边都可能会这样做,并且需要 O(|V|) 次删除最小操作,因为您必须这样做才能将顶点从队列中取出。

如果您使用斐波那契堆作为优先队列,则减少键需要恒定时间,但删除分钟需要 O(log |V|) 时间,因此您得到 O(|E| + |V| log |V|) . 就 |V| 而言只有,|E| 被替换为 O(|V| 2 ),因为它可能会变得那么高,并且支配着 |V| 日志 |V| 项给出 O(|V| 2 ) 的总复杂度。

所以如果你想给 |V| 一个界限,你是对的仅,但在 |V| 方面给出了一个界限和 |E| 分开是首选,因为它传达了更多的信息 它告诉您对于稀疏图,它比 O(|V| 2 ) 快,这可能很重要。

请注意,您查找的 O(V + E log V) 用于使用不同类型的优先级队列(如二元堆)而不是斐波那契堆的实现。 这在实践中很常见。

您只考虑全连接图的情况。 big-O 表示法适用于给定某些输入参数的最坏情况,并且由于给定的复杂性使用 V 和 E,这意味着全连接图无关紧要。 对于一般的图形,Dijkstra 算法将在 O(V+ElogV) 或更快的速度上完成; 对于全连接图,当 E 大约为 (V^2)/2 时,它将在 O(V^2) 内完成,这确实比 O(V+((V^2)/2)logV) 快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM