【发布时间】:2016-04-28 16:48:32
【问题描述】:
我已阅读以下内容,但请查看下面的代码。
Why Dijkstra's Algorithm uses heap (priority queue)?
我有两个版本的 dijkstra,一个带有 PQueue 的好版本,一个带有常规链表队列的坏版本。
public static void computeDijkstra(Vertex source) {
source.minDistance = 0.;
Queue<Vertex> vertexQueue = new PriorityQueue<Vertex>();
// Queue<Vertex> vertexQueue = new LinkedList<Vertex>();
vertexQueue.add(source);
while (!vertexQueue.isEmpty()) {
Vertex fromVertex = vertexQueue.poll();
if (fromVertex.neighbors != null) {
for (Edge currentEdge : fromVertex.neighbors) {
Vertex toVertex = currentEdge.target;
if (currentEdge.weight + fromVertex.minDistance < toVertex.minDistance) {
toVertex.minDistance = currentEdge.weight + fromVertex.minDistance;
toVertex.previous = fromVertex;
vertexQueue.add(toVertex);
}
}
}
}
}
public static void computeDijkstraBad(Vertex source) {
source.minDistance = 0.;
// Queue<Vertex> vertexQueue = new PriorityQueue<Vertex>();
Queue<Vertex> vertexQueue = new LinkedList<Vertex>();
vertexQueue.add(source);
while (!vertexQueue.isEmpty()) {
Vertex fromVertex = vertexQueue.poll();
if (fromVertex.neighbors != null) {
for (Edge currentEdge : fromVertex.neighbors) {
Vertex toVertex = currentEdge.target;
if (currentEdge.weight + fromVertex.minDistance < toVertex.minDistance) {
toVertex.minDistance = currentEdge.weight + fromVertex.minDistance;
toVertex.previous = fromVertex;
vertexQueue.add(toVertex);
}
}
}
}
}
我还使用如下文本文件创建图形
0, 1, 2, 3, 4, 5, 6 // vertices
0, 6 // from and to vertex
1, (2-5, 0-4, 4-6) // from vertex 1 it will have edge to 2 with weight 5 ...
0, (4-3, 3-7)
4, (2-11, 3-8)
3, (2-2, 5-5)
2, (6-2, 5-10)
5, (6-3)
两种实现都呈现以下[0, 3, 2, 6],它确实是从 0 到 6 的最短路径!
现在我们知道,如果使用 Simple BFS 来寻找正整数的最短距离,就会出现找不到最小路径的情况。那么,有人可以给我一个反例,我的 Bad 实现将无法打印图表的正确路径。随时以我使用的图形格式(示例文本文件格式)给我答案。
到目前为止,我所拥有的所有图表,两种实现都呈现了正确的结果。这不应该发生,因为糟糕的实现是运行时 (E+V),我们知道如果没有至少 E log V,我们就无法找到最短路径。
另一个例子,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
0, 10
0, (1-9, 2-10, 3-11)
1, (4-1, 5-7)
2, (4-4, 5-3, 6-5)
3, (5-1, 6-4)
4, (7-9, 8-14, 5-3)
5, (7-4, 8-5, 9-9, 6-2)
6, (8-2, 9-2)
7, (10-3)
8, (10-2)
9, (10-5)
两种实现都渲染 [0, 3, 5, 6, 8, 10],这是从 0 到 10 的正确最短路径。
【问题讨论】:
-
只是来这里说你的糟糕实现也是O(E logV)。实际上,Dijkstra 的实现并没有改善最坏的情况,所以它并没有改变 BigO 的情况,但它提高了普通情况的性能
-
嗨,你能详细说明为什么坏的是E log v吗?这是一个简单的 BFS,具有恒定时间的链表插入和删除。
-
您拥有与良好实现相同的循环结构。唯一的区别是测试的顺序。在更好的 Dijkstra 中,当您发现第一个完整的解决方案并确定它是最佳解决方案时,您可以停下来,这就是为什么在常见情况下它被认为更好的原因。在您的代码上,两者都具有相同的运行时间,因为它们都检查所有边缘(但这不是必需的)
-
另外,您在顶点上有一个循环,对于每个顶点,边上都有一个循环。这绝对不是 E+V。