具有列表列表的 Floyd-Warshall 算法实现
Floyd-Warshall algorithm implementation with list of lists
我想使用 Floyd-Warshall 算法找到两个顶点之间的最短路径。矩阵位于 ArrayList> 中。它总是相当小,例如 4x4 或 8x8 矩阵。
在我的 class 中,我已经有了一个距离矩阵。我只是想创建 "shortest path" 矩阵。但它不起作用。它填错了我的矩阵。
我真的希望有人能看看这个并解释哪里出了问题。
我的距离矩阵是:
0 0 256 411
556 0 558 0
250 0 0 431
0 0 431 0
测试输出为:
0 0 0 0
556 556 556 556
250 250 250 250
0 0 0 0
预计:
500 0 842 681
556 0 806 967
0 0 500 681
581 0 0 862
我已经注释掉了我的测试输出。 distance
是我的矩阵,顶点之间的距离是整数值。在我的矩阵中,i
是 y,j
是 x。
public ArrayList<ArrayList<Integer>> calcShortest() {
//String test = "";
ArrayList<ArrayList<Integer>> shortest = distance;
for (int k = 0; k < airports.size(); k++) {
for (int i = 0; i < airports.size(); i++) {
for (int j = 0; j < airports.size(); j++) {
shortest.get(j).add(i, Math.min(shortest.get(k).get(i) + shortest.get(j).get(k),
shortest.get(j).get(i)));
}
}
}
/*for (int j = 0; j < airports.size(); j++) {
for (int i = 0; i < airports.size(); i++) {
test += shortest.get(j).get(i) + " ";
}
System.out.println(test);
test = "";
}*/
return shortest;
}
试试这个:
shortest.get(j).add(i, Math.min(shortest.get(i).get(k) + shortest.get(k).get(j),
shortest.get(i).get(j)));
或者使用Dijkstra算法
您的代码和数据存在许多问题。
add
操作 shortest.get(j).add(i, ...)
将一个元素插入 ArrayList
。您实际上要设置一个值:shortest.get(j).set(i, ...)
数组索引错误。您正在尝试 shortest[j][i] = min(shortest[k][i] + shortest[j][k], shortest[j][i])
,但 Floyd-Warshall 要求 shortest[i][j] = min(shortest[i][k] + shortest[k][j], shortest[i][j])
.
您的预期输出没有意义。 shortest[2][2]
怎么可能是500?我们已经知道它是 0。你如何计算 shortest[3][0]
是 581?无法从您提供的距离矩阵中得到 581。
在距离矩阵中,为什么对角线上的值为零?比如distance[1][3]
就是0。那么节点1到节点3的距离就是0?真的吗?
为什么要让 shortest
引用 distance
?既然你正在修改 distance
,为什么不直接使用 distance
而不是假装你有一个名为 shortest
的不同矩阵?或者您打算复制 distance
?
下面的代码可以正确运行 Floyd-Warshall,因为它调用 set
来修改 ArrayList
并且它使用了正确的索引。但是,它不会为您的距离矩阵产生您所说的 "expected" 结果,因为正如我所解释的,您的预期结果没有意义并且距离矩阵本身是可疑的。
int n = shortest.size();
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
shortest.get(i).set(j,
Math.min(shortest.get(i).get(k) + shortest.get(k).get(j),
shortest.get(i).get(j)));
}
}
}
我想使用 Floyd-Warshall 算法找到两个顶点之间的最短路径。矩阵位于 ArrayList
在我的 class 中,我已经有了一个距离矩阵。我只是想创建 "shortest path" 矩阵。但它不起作用。它填错了我的矩阵。
我真的希望有人能看看这个并解释哪里出了问题。
我的距离矩阵是:
0 0 256 411
556 0 558 0
250 0 0 431
0 0 431 0
测试输出为:
0 0 0 0
556 556 556 556
250 250 250 250
0 0 0 0
预计:
500 0 842 681
556 0 806 967
0 0 500 681
581 0 0 862
我已经注释掉了我的测试输出。 distance
是我的矩阵,顶点之间的距离是整数值。在我的矩阵中,i
是 y,j
是 x。
public ArrayList<ArrayList<Integer>> calcShortest() {
//String test = "";
ArrayList<ArrayList<Integer>> shortest = distance;
for (int k = 0; k < airports.size(); k++) {
for (int i = 0; i < airports.size(); i++) {
for (int j = 0; j < airports.size(); j++) {
shortest.get(j).add(i, Math.min(shortest.get(k).get(i) + shortest.get(j).get(k),
shortest.get(j).get(i)));
}
}
}
/*for (int j = 0; j < airports.size(); j++) {
for (int i = 0; i < airports.size(); i++) {
test += shortest.get(j).get(i) + " ";
}
System.out.println(test);
test = "";
}*/
return shortest;
}
试试这个:
shortest.get(j).add(i, Math.min(shortest.get(i).get(k) + shortest.get(k).get(j),
shortest.get(i).get(j)));
或者使用Dijkstra算法
您的代码和数据存在许多问题。
add
操作shortest.get(j).add(i, ...)
将一个元素插入ArrayList
。您实际上要设置一个值:shortest.get(j).set(i, ...)
数组索引错误。您正在尝试
shortest[j][i] = min(shortest[k][i] + shortest[j][k], shortest[j][i])
,但 Floyd-Warshall 要求shortest[i][j] = min(shortest[i][k] + shortest[k][j], shortest[i][j])
.您的预期输出没有意义。
shortest[2][2]
怎么可能是500?我们已经知道它是 0。你如何计算shortest[3][0]
是 581?无法从您提供的距离矩阵中得到 581。在距离矩阵中,为什么对角线上的值为零?比如
distance[1][3]
就是0。那么节点1到节点3的距离就是0?真的吗?为什么要让
shortest
引用distance
?既然你正在修改distance
,为什么不直接使用distance
而不是假装你有一个名为shortest
的不同矩阵?或者您打算复制distance
?
下面的代码可以正确运行 Floyd-Warshall,因为它调用 set
来修改 ArrayList
并且它使用了正确的索引。但是,它不会为您的距离矩阵产生您所说的 "expected" 结果,因为正如我所解释的,您的预期结果没有意义并且距离矩阵本身是可疑的。
int n = shortest.size();
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
shortest.get(i).set(j,
Math.min(shortest.get(i).get(k) + shortest.get(k).get(j),
shortest.get(i).get(j)));
}
}
}