在 java 中停止循环
stop for loop in java
我编写了计算最简单最速下降算法的代码,其中有一个 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
我不知道这是否是真正的问题,但您永远不应该使用双精度来检查完全相等。这是因为使用 double 的乘法或除法等运算很可能不准确。最好选择一些小数 epsilon>0
并检查你的 double 的绝对值是否小于 epsilon。
我编写了计算最简单最速下降算法的代码,其中有一个 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
我不知道这是否是真正的问题,但您永远不应该使用双精度来检查完全相等。这是因为使用 double 的乘法或除法等运算很可能不准确。最好选择一些小数 epsilon>0
并检查你的 double 的绝对值是否小于 epsilon。