在java中停止for循环

时间:2016-05-02 13:32:26

标签: java loops mathematical-optimization

我编写的代码计算了最简单的最速下降算法,并且有一个for循环的迭代。

当x1,x2的值与最小化器相同时,它应该停止循环。但是在我的代码中却没有,而是一次又一次地打印最小化值。

这是我的代码:

for (int i = 0 ; i < MAX ; i++) {
    // ∇ƒ(x) =
    //     | 2(x1 - a) - c(x2 - b) |
    //     | 2(x2 - b) - c(x1 - a) |
    //
    // Apply x to ∇ƒ(x)
    double d1f1 = 2 * (x1 - a) - c * (x2 - b);
    double d1f2 = 2 * (x2 - b) - c * (x1 - a);

    // ∇²ƒ(x) =
    //     | 2    -c |
    //     | -c   2  |
    double d2f1 =  2.0;
    double d2f2 = -c;

    //we reach to the minimizer 
    if (d1f1 == 0 && d1f2 == 0)
    { 
        break;
    }

    // α = |d1f1 d1f2| * | d2f1 d2f2 | * | d1f1 | 
    //                   | d2f2 d2f1 |   | d1f2 |
    alpha = (d1f1 * d1f1 + d1f2 * d1f2) /
        (d1f1 * (d1f1 * d2f1 + d1f2 * d2f2) +
         d1f2 * (d1f1 * d2f2 + d1f2 * d2f1));

    // x1 = |x1| - α * | d1f1 |
    // x2 = |x2| - α * | d1f2 |
    x1 = x1 - alpha * d1f1;
    x2 = x2 - alpha * d1f2;

    // Debug
    System.out.println("");
    System.out.printf("alpha  = %.2f\n", alpha);
    System.out.printf("x1     = %.2f\n", x1);
    System.out.printf("x2     = %.2f\n", x2);
}

结果:

a  = 5.00
x1 = 1.00
x2 = 4.00

alpha  = 0.28
x1     = 4.11
x2     = 1.11

alpha  = 2.47
x1     = 4.96
x2     = 2.02

alpha  = 0.28
x1     = 4.99
x2     = 1.99

alpha  = 2.47
x1     = 5.00
x2     = 2.00

alpha  = 0.28
x1     = 5.00
x2     = 2.00

alpha  = 2.47
x1     = 5.00
x2     = 2.00

alpha  = 0.28
x1     = 5.00
x2     = 2.00

alpha  = 2.47
x1     = 5.00
x2     = 2.00

alpha  = 0.28
x1     = 5.00
x2     = 2.00

alpha  = 2.47
x1     = 5.00
x2     = 2.00

alpha  = 0.28
x1     = 5.00
x2     = 2.00

alpha  = 2.47
x1     = 5.00
x2     = 2.00

alpha  = 0.28
x1     = 5.00
x2     = 2.00

alpha  = 2.47
x1     = 5.00
x2     = 2.00

alpha  = 0.28
x1     = 5.00
x2     = 2.00

alpha  = 2.17
x1     = 5.00
x2     = 2.00

alpha  = 0.28
x1     = 5.00
x2     = 2.00

alpha  = 2.50
x1     = 5.00
x2     = 2.00
final result
x1     = 5.00
x2     = 2.00

1 个答案:

答案 0 :(得分:1)

我不知道这是不是真正的问题,但你永远不应该使用双打检查确切的相等性。这是因为使用double的乘法或除法等操作很可能不准确。最好选择一些小数epsilon>0并检查双精度的绝对值是否小于epsilon。