在Java中迭代集合时递增值时出现的奇怪错误

时间:2015-07-11 20:47:55

标签: java debugging collections

我最近编写了一个在图表上执行蚁群优化的程序。

以下代码中有一个我无法理解的错误。

    Map<Node, Edge> nodesLinkedToCurrentNode = a.getCurrentNode().getLinkedNodes();

    TreeMap<Double, Node> probabilitiesForNodes = new TreeMap<>();
    double totalProb = 0d;

    for (Node n : graph.values()) {
        if (!a.getVisited().contains(n)) {
            //For each node that has not yet been visited
            //calculate it's weighted probabily
            double weightedProbability
                    = (Math.pow(nodesLinkedToCurrentNode.get(n).getPheremoneLevel(), RPI))
                    * (Math.pow((double) 1 / nodesLinkedToCurrentNode.get(n).getDistance(), RHI));
            totalProb += weightedProbability;

            //Map the node to its probability
            probabilitiesForNodes.put(weightedProbability, n);
        }
    }

    double testTotalProb = 0d;
    for (Double d : probabilitiesForNodes.keySet()) {
        testTotalProb += d;
    }
    if (testTotalProb != totalProb) { <----------How can this happen??
        System.out.println("Why?");
        totalProb = testTotalProb;
    }

if语句一直在执行,我不明白为什么。

我只是递增一个值,但由于某种原因,它没有正确递增。

I made the project open source, if you want to check it out

The java file with the code in it

我使用以下代码复制了错误:

    TreeMap<Double, String> probabilitiesForNodes = new TreeMap<>();
    double totalProb = 0d;

    for (int i = 1; i < 10; i++) {
        //For each node that has not yet been visited
        //calulate it's weighted probabily
        double weightedProbability
                = (Math.pow(0.7 + 1 / i, 2))
                * (Math.pow((double) 1 / 30, i));
        totalProb += weightedProbability;

        String sudoNode = "node" + i;

        //Map the node to its probability
        probabilitiesForNodes.put(weightedProbability, sudoNode);
    }

    double testTotalProb = 0d;
    for (Double d : probabilitiesForNodes.keySet()) {
        testTotalProb += d;
    }
    if (testTotalProb != totalProb) {
        System.out.println("Why?");
        totalProb = testTotalProb;
    }

1 个答案:

答案 0 :(得分:4)

您正在使用double号码,因此您应该期待这一点。具体而言,您可以通过迭代添加相同的totalProb数字来获得testTotalProbdouble,但顺序不同。由于添加双精度不是完全关联的操作,因此会出现足够的差异以使您的相等测试失败。

可能发生的另一件事是在同一Double密钥上发生冲突。没有什么能阻止两个节点具有完全相同的加权概率。所以对于初学者来说,你可以检查两个系列的大小。