gpt4 book ai didi

java - 修改Dijkstra,需要验证

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:08:00 25 4
gpt4 key购买 nike

Dijkstra 算法有一个步骤提到“选择具有最短路径的节点”。我意识到如果我们不从图/队列中抛出一个节点,这一步是不必要的。据我所知,这很有效,没有已知的缺点。这是代码。如果失败请指导我?如果是那么怎么办? [编辑 => 此代码已经过测试并且运行良好,但有可能我的测试用例并不详尽,因此将其发布在 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;
}

最佳答案

问题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 );
}

问题2

您还需要使用类似的方法将 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 差很多,但我会对它在实践中的表现感兴趣。我的猜测是它适用于稀疏的几乎像树一样的图,但不适用于密集的图。

关于java - 修改Dijkstra,需要验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19201905/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com