0
double findaroot(double x1, double x2){ //finds the root between two values
    double gap = Math.abs(x1 - x2); //find the initial interval
    while(gap > INTERVAL) { //check for precision           
        gap = gap / 2; //halve the interval
        double x3 = x1 + gap;
        if (f(x3) == 0) { //check for symmetry
            return x3;
        } else if (Math.signum(f(x1)) == Math.signum(f(x3))){
            x1 = x3; //redefine the interval
        } else {
            x2 = x3; //redefine the interval
        }
        findaroot(x1, x2); //call again
    }
    return (x1 + x2) / 2; //return the mean
}

我试图在区间(-143、0.222222)中找到 f(x)=-21x^2+10x-1 的解决方案。指导方针规定我应该实施一个二分法来解决这个问题。目前,此方法适用于我必须通过的 10 个测试用例中的 8 个,但对于上述值,它会给出“超出时间限制”错误。给定间隔之间的精度水平至少为“0.000001”的情况下,近似根需要 15 秒。

我不确定如何在不改变方法的情况下提高效率。我已经实现了霍纳的计算函数的方法,因为Math.pow(x1, x2)它花费的时间太长。

4

2 回答 2

1

只需删除该行findaroot(x1, x2);。无论如何,您都没有使用此递归函数调用的结果。

编辑:这是您的代码的递归版本(未经测试)

double findaroot(double x1, double x2){ //finds the root between two values
    double gap = Math.abs(x1 - x2); //find the initial interval
    if (gap > INTERVAL) { //check for precision           
        gap = gap / 2; //halve the interval
        double x3 = x1 + gap;
        if (f(x3) == 0) { //check for symmetry
            return x3;
        } else if (Math.signum(f(x1)) == Math.signum(f(x3))){
            x1 = x3; //redefine the interval
        } else {
            x2 = x3; //redefine the interval
        }
        return findaroot(x1, x2);
    }
    else
         return (x1 + x2) / 2; //return the mean
}
于 2013-09-23T10:29:39.217 回答
0

正如其他人已经说过的那样: findaroot 的递归调用是错误的/不需要的。这段代码对我有用:

private final int NMAX = 100;

public double solve(Function f, double a, double b, double tolerance) {
    if (a >= b) throw new IllegalArgumentException("illegal interval!");

    double fa = f.value(a);
    if (Math.signum(fa) == Math.signum(f.value(b))) throw new IllegalArgumentException("solution not within interval!");

    for (int n = 0; n < NMAX; n++) {
        double c = (a + b) / 2;

        double fc = f.value(c);
        if ((fc == 0.0) || ((b - a) / 2 < tolerance)) {
            // solution found
            return c;
        }

        // adapt interval
        if (Math.signum(fc) == Math.signum(fa)) {
            a = c;
            fa = fc;
        } else {
            b = c;
        }
    }

    return Double.NaN;
}
于 2013-09-23T10:56:38.590 回答