我编写的代码计算了最简单的最速下降算法,并且有一个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
答案 0 :(得分:1)
我不知道这是不是真正的问题,但你永远不应该使用双打检查确切的相等性。这是因为使用double的乘法或除法等操作很可能不准确。最好选择一些小数epsilon>0
并检查双精度的绝对值是否小于epsilon。