Floyd算法的Java实现不适用于无向图

时间:2017-07-05 17:33:45

标签: java algorithm shortest-path floyd-warshall

我得到了Floyd算法的以下实现,用于在加权图中找到最短路径。结果是所有顶点之间最短路径的矩阵:

class FloydWarshall {

static int graph [][] = {   {0, 5, 3},
                            {5, 0, 0},
                            {3, 0, 0}
                        };

public static void main(String args[]) {

    int N=graph.length;
    int y, x, j;

    for (y = 0; y < N; y++)
        for (x = 0; x < N; x++)
            if (graph[x][y] > 0) 
                for (j = 0; j < N; j++)
                    if (graph[y][j] > 0)
                        if ((graph[x][j] == 0) || (graph[x][y] + graph[y][j] < graph[x][j]))
                            graph[x][j] = graph[x][y]+graph[y][j];
    for (y = 0; y < N; y++) {
        for (x = 0; x < N; x++)
            System.out.print(graph[y][x] < 0 ? "  "+graph[y][x] : " "+graph[y][x]);
        System.out.println();
    }
}

}

奇怪的是,即使它正在工作,它也不会计算从无向图的顶点到自身(应该为0)的正确距离。例如,下图:

{0, 5, 3}
{5, 0, 0}
{3, 0, 0}

得到输出:

6 5 3
5 10 8
3 8 6

而不是:

0 5 3
5 0 8
3 8 0

我认为代码中只有一个愚蠢的错误,但我无法找到它,所以我感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

问题如下:您在实现中以两种相反的方式使用值0:

  • 要表明xy之间没有边缘,您可以将graph[x][y]设置为0,正如支票if (graph[x][y] > 0)所见,{{1 }}

  • 表示两个节点之间的距离为0。

所以你得到的对角线条实际上告诉你:涉及我的顶点的最短非平凡循环是什么?

我建议您使用非常大的数字(if (graph[y][j] > 0),注意溢出!)来表示非边缘或更好:将邻接信息存储在完全独立的矩阵中。