gpt4 book ai didi

java - 使用最小堆实现 Dijkstra 算法但失败

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

我正在尝试在 Java 中使用最小堆实现 Dijkstra 算法,但每次都得到错误的输出。 Here我在 C++ 中找到了相同的主题。下面是我的图表。绿色的节点 A 是源,红色的节点 F 是目标。我的目标是找出从 A 到 F 的最短路径长度。

This is my graph

下面是我的代码

public class Dijkstra {
private static Heap heap = new Heap();
private static int[][] graph;

public Dijkstra() {
graph = new int[6][6];
/*
* The graph value assignment is just for checking the code. node A is
* referred as node 0, node B is referred as node 1 and so on. finally
* node F is referred as node 5.
*/
graph[0][0] = graph[0][1] = graph[0][3] = graph[0][4] = graph[0][5] = graph[1][0] = graph[1][1] = graph[1][4] = graph[1][5] = graph[2][2] = graph[2][5] = graph[3][0] = graph[3][3] = graph[4][0] = graph[4][1] = graph[4][4] = graph[5][0] = graph[5][1] = graph[5][2] = graph[5][5] = 0;
graph[1][2] = graph[2][1] = graph[2][3] = graph[3][2] = graph[3][4] = graph[4][3] = graph[4][5] = graph[5][4] = 1;
graph[1][3] = graph[3][1] = 3;
graph[0][2] = graph[2][0] = 4;
graph[2][4] = graph[4][2] = 5;
graph[3][5] = graph[5][3] = 8;
}

public static void main(String[] args) {
Dijkstra dij = new Dijkstra();
// Source is node A (node 0) and destination is node F (node 5)
System.out.println(dij.solve(6, 0, 5));
}

public int solve(int numOfNodes, int source, int dest) {
heap.push(source, 0);
while (!heap.isEmpty()) {
int u = heap.pop();
if (u == dest)
return heap.cost[dest];
for (int i = 0; i < numOfNodes; i++) {
if (graph[u][i] >= 0)
heap.push(i, heap.cost[u] + graph[u][i]);
}
}
return -1;
}
}

class Heap {
private int[] data;
private int[] index;
public int[] cost;
private int size;

public Heap() {
data = new int[6];
index = new int[6];
cost = new int[6];

for (int i = 0; i < 6; i++) {
index[i] = -1;
cost[i] = -1;
}

size = 0;
}

public boolean isEmpty() {
return (size == 0);
}

private void shiftUp(int i) {
int j;
while (i > 0) {
j = (i - 1) / 2;
if (cost[data[i]] < cost[data[j]]) {
// swap here
int temp = index[data[i]];
index[data[i]] = index[data[j]];
index[data[j]] = temp;
// swap here
temp = data[i];
data[i] = data[j];
data[j] = temp;
i = j;
} else
break;
}
}

private void shiftDown(int i) {
int j, k;
while (2 * i + 1 < size) {
j = 2 * i + 1;
k = j + 1;
if (k < size && cost[data[k]] < cost[data[j]]
&& cost[data[k]] < cost[data[i]]) {
// swap here
int temp = index[data[k]];
index[data[k]] = index[data[i]];
index[data[i]] = temp;
// swap here
temp = data[k];
data[k] = data[i];
data[i] = temp;

i = k;
} else if (cost[data[j]] < cost[data[i]]) {
// swap here
int temp = index[data[j]];
index[data[j]] = index[data[i]];
index[data[i]] = temp;
// swap here
temp = data[j];
data[j] = data[i];
data[i] = temp;

i = j;
} else
break;
}
}

public int pop() {
int res = data[0];
data[0] = data[size - 1];
index[data[0]] = 0;
size--;
shiftDown(0);
return res;
}

public void push(int x, int c) {
if (index[x] == -1) {
cost[x] = c;
data[size] = x;
index[x] = size;
size++;
shiftUp(index[x]);
} else {
if (c < cost[x]) {
cost[x] = c;
shiftUp(index[x]);
shiftDown(index[x]);
}
}
}
}

在运行整个代码时,我得到 0 作为输出,但可以清楚地看出从节点 A 到节点 F 的成本是 7 (4+1+1+1 = A-C-D-E-F)。哪里出错了?

最佳答案

您使用 graph[u][i] >= 0 测试现有边。但是您的图形被定义为没有零值边缘。所以你应该把它改成

if (graph[u][i] > 0) ...

内部方法解决。另一种可能性是在矩阵中用 -1 值标记不存在的边。这也将允许零成本边缘。

关于java - 使用最小堆实现 Dijkstra 算法但失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10076532/

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