Dijkstra算法有一个步骤,提到“选择最短路径的节点”。我意识到这一步是unnecessary if we dont throw a node out of the graph/queue
。这在我的知识中很有效,没有已知的缺点。这是代码。请告诉我它是否失败?如果确实如此呢? [编辑=>这个代码是经过测试并且工作得很好,但是有一个机会,我的测试案例没有那么多,这就是在STACKOVERFLOW上发布了]
public Map<Integer, Integer> findShortest(int source) {
final Map<Integer, Integer> vertexMinDistance = new HashMap<Integer, Integer>();
final Queue<Integer> queue = new LinkedList<Integer>();
queue.add(source);
vertexMinDistance.put(source, 0);
while (!queue.isEmpty()) {
source = queue.poll();
List<Edge> adjlist = graph.getAdj(source);
int sourceDistance = vertexMinDistance.get(source);
for (Edge edge : adjlist) {
int adjVertex = edge.getVertex();
if (vertexMinDistance.containsKey(adjVertex)) {
int vertexDistance = vertexMinDistance.get(adjVertex);
if (vertexDistance > (sourceDistance + edge.getDistance())) {
//previous bug
//vertexMinDistance.put(adjVertex, vertexDistance);
vertexMinDistance.put(adjVertex, sourceDistance + edge.getDistance())
}
} else {
queue.add(adjVertex);
vertexMinDistance.put(adjVertex, edge.getDistance());
}
}
}
return vertexMinDistance;
}
答案 0 :(得分:1)
我认为代码中有一个错误:
int vertexDistance = vertexMinDistance.get(adjVertex);
if (vertexDistance > (sourceDistance + edge.getDistance())) {
vertexMinDistance.put(adjVertex, vertexDistance);
}
因为这没有效果(adjVertex的vertexMinDistance被设置回原始值)。
更好的是:
int vertexDistance = vertexMinDistance.get(adjVertex);
int newDistance = sourceDistance + edge.getDistance();
if (vertexDistance > newDistance ) {
vertexMinDistance.put(adjVertex, newDistance );
}
您还需要使用以下内容将adjVertex添加到队列中:
int vertexDistance = vertexMinDistance.get(adjVertex);
int newDistance = sourceDistance + edge.getDistance();
if (vertexDistance > newDistance ) {
vertexMinDistance.put(adjVertex, newDistance );
queue.add(adjVertex);
}
如果您不这样做,那么您将得到错误的答案,例如:
A->B (1)
A->C (10)
B->C (1)
B->D (10)
C->D (1)
正确的路径是权重为3的A-> B-> C-> D,但是没有修改,那么我相信你的算法将选择更长的路径(因为它一旦找到它就不会重新检查C一条较短的路径)。
通过这些修改,我认为这种方法基本上是合理的,但是你应该注意计算的复杂性。
Dijkstra只需绕过主循环V次(其中V是图中顶点的数量),而您的算法可能需要更多循环用于某些图形。
您仍会得到正确答案,但可能需要更长时间。
虽然最坏情况的复杂性会比Dijkstra差很多,但我会对它在实践中的表现感兴趣。我的猜测是它适用于稀疏的几乎像树的图形,但对于密集图形则不太好。