Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 贝尔曼·福特随机产生错误结果_Java_Algorithm_Bellman Ford - Fatal编程技术网

Java 贝尔曼·福特随机产生错误结果

Java 贝尔曼·福特随机产生错误结果,java,algorithm,bellman-ford,Java,Algorithm,Bellman Ford,我试图从CLRS中实现Bellman-Ford算法,它似乎在距离度量上随机溢出。我的代码如下: private void initSingleSource(Vertice source) { for(Vertice vertice:vertices) { vertice.distance = Integer.MAX_VALUE; vertice.predecessor = null; } source.distance = 0; } pr

我试图从CLRS中实现Bellman-Ford算法,它似乎在距离度量上随机溢出。我的代码如下:

private void initSingleSource(Vertice source) {
    for(Vertice vertice:vertices) {
        vertice.distance = Integer.MAX_VALUE;
        vertice.predecessor = null;
    }
    source.distance = 0;
}

private void relax(Vertice u, Vertice v, int weight) {
    if(v.distance > u.distance + weight) {
        v.distance = u.distance + weight;
        v.predecessor = u;
    }
}

public boolean bellmanFord(Vertice source) {
    initSingleSource(source);
    for(int i = 0; i < vertices.size()-1; i++) {
        for(Vertice u: edges.keySet()) {
            Hashtable<Vertice, Integer> table = edges.get(u);
            for(Vertice v: table.keySet()) {
                 relax(u, v, table.get(v));
            }
        }
    }
    for(Vertice u: edges.keySet()) {
        Hashtable<Vertice, Integer> table = edges.get(u);
        for(Vertice v: table.keySet()) {
             if(v.distance > u.distance + table.get(v)) {
                 return false;
             }
        }
    }

    return true;
}
我随机得到的正确答案是:

B2C4D7E-2

否则我会得到:

B-2147483636 C-2147483634 D-2147483631 E-2147483640


知道为什么会发生这种情况吗?

我认为当使用
u
调用
relax
时会出现问题,从而
u.distance
equals
Integer.MAX\u值
。然后
u.距离+重量
为负(总和超出界限)。该负值小于
v.distance
,并被分配到
v.distance

这可能会发生,也可能不会发生,具体取决于
relax
调用的顺序。使用
table.keySet()
时,顺序是随机的。如果你有幸按照DFS的顺序考虑顶点,你应该得到正确的结果,但这是不可能的。 可能的解决方案

private void relax(Vertice u, Vertice v, int weight) {
    if(u.distance != Integer.MAX_VALUE && v.distance > u.distance + weight) {
        v.distance = u.distance + weight;
        v.predecessor = u;
    }
}

提示:table.keySet()可能不会为不同的运行生成相同的顺序。这似乎是一个很好的解决方案。但现在我想知道,我是否应该使用
keySet()
在边上迭代?似乎是引入非确定性bug的一种糟糕方式。对于这种情况,首选的数据结构/迭代方法是什么?我不认为
keySet()
不好。它确保您的算法不依赖于顶点的顺序。如果它不是随机的,那么您可以有一个测试用例,尽管存在bug,但它运行良好,并且不会发现它。
private void relax(Vertice u, Vertice v, int weight) {
    if(u.distance != Integer.MAX_VALUE && v.distance > u.distance + weight) {
        v.distance = u.distance + weight;
        v.predecessor = u;
    }
}