【问题标题】:Floyd-Warshall Algorithm - Representing "infinity"Floyd-Warshall 算法 - 表示“无穷大”
【发布时间】:2014-06-28 11:52:03
【问题描述】:

使用 Floyd-Warshall 的算法来寻找两个顶点之间的最短路径,在 Java 中实现时我应该如何表示无穷大?我这里用无穷大表示两个顶点之间没有路径。

谢谢

【问题讨论】:

    标签: java graph shortest-path floyd-warshall


    【解决方案1】:

    答案取决于您用来表示权重的数据类型。如果是double,您可以安全地使用Double.POSITIVE_INFINITY。如果它是一个整数,请选择一个您不使用的值,例如如果您的图表不允许负边,则为负数。

    这样做的一个不幸结果是,您需要注意三个循环中的无穷大元素:而不是使用“直接”加法,您需要检查它是否是特殊的“无穷大”值,并且只然后做加法:

    final int INFINITY = -1;
    ...
    for (int k = 0 ; k != N ; k++) {
        for (int i = 0 ; i != N ; i++) {
            for (int j = 0 ; j != N ; j++) {
                if (g[i][k] == INFINITY || g[k][j] == INFINITY) continue;
                int total = g[i][k] + g[k][j];
                if (g[i][j] != INFINITY) {
                    g[i][j] = Math.min(g[i][j], total);
                } else {
                    g[i][j] = total;
                }
            }
        }
    }
    

    【讨论】:

    • 如果我们使用 Integer,并且我们不想检查元素是否为 INFINITY/null 等。我们可以使用 Integer.MAX_VALUE 吗?与执行 Math.min 评估时一样,其他值总是更小。
    • @DJDMorrison 不,您不能在没有额外检查的情况下使用Integer.MAX_VALUE,因为向Integer.MAX_VALUE 添加任何内容都会导致溢出。当您比较 g[i][j]g[i][k]+g[k][j] 时,这会导致不正确的结果。
    • 既然你确保你没有向INFINITY求和,你不妨写这个INFINITY = Integer.MAX_VALUE
    【解决方案2】:

    如果你使用Integer/LongFloat/Double而不是int/longfloat/double,那么你可以用null的值来表示无穷大。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-18
      • 1970-01-01
      • 2014-06-19
      • 2018-11-11
      • 1970-01-01
      • 2011-02-10
      • 1970-01-01
      • 2015-11-19
      相关资源
      最近更新 更多