如何回滚返回特定值的递归函数

时间:2014-09-21 09:25:13

标签: java recursion divide-and-conquer

您好,感谢您的时间和支持。

我的广义问题是:如何在必须返回特定值的递归函数中回滚?

我的具体案例:

在这个问题中,我必须检查给定多项式是否在给定区间内有任何根,由它的边距定义:x1和x2。

我必须通过连续减半间隔[x1,x2]来做到这一点,直到它们之间的差值最多接近零(对于这个值,我使用 foundroot 变量),在这种情况下,找到了一个根。

此过程由递归 findaroot 方法完成,参数为x1和x2(间隔边距)。

以下是该方法的工作原理:

  1. 该方法首先检查 f(x1) f(x2)(x1和x2中函数的值)的值是否具有相同的符号,在这种情况下,区间内没有根,并返回 noroot 值;

  2. 然后,它检查是否找到了根(如果 x1 - x2 < = foundroot );

  3. 如果找不到根,则返回其中一个间隔的返回值之间的最小值, noroot 在我的情况下是一个非常高的数字。当然,如果root超过 noroot 的值,则不起作用。

  4. 我的问题是:

    • 正如广义问题所述,除了将返回值与高/低/不容易获得的数字进行比较之外,我应该如何使该方法适用于所有情况?

    这是我的书面代码:

        //found root variable + value assigned if root is not found in interval (x1,x2)
        static final double foundroot = 0.000001;
        static final double noroot=999999;
    
        //finds root
        static double findaroot(double x1, double x2)
        {
            if(  Math.signum( f(x1,0) ) == Math.signum( f(x2,0) )  )
            {
                return noroot;
            }
            else
            {
                if(Math.abs(x1-x2)<=foundroot)
                {
                    return x1;
                }
                else
                {
                    return Math.min( findaroot(x1,(x1+x2)/2) , findaroot((x1+x2)/2,x2));
                }
            }
        }
    

    如果有任何不清楚的地方,请询问。如果您认为我的问题/标题不明确或不清楚,请告诉我如何修改它们。

    我将尽力澄清,以提供清晰的描述,并希望有一个明确的答案。

    谢谢!

1 个答案:

答案 0 :(得分:1)

使用有意义的返回值可以避免使用幻数(无根)。在这种情况下,您可以考虑切换到Double而不是double,并使用null值作为“无结果”指示符。

这可以一般地应用:如果您使用递归函数来计算某个结果,但也需要转义,则使用null值是可接受的转义。您可以考虑复合答案,以防您需要多于1个转义(例如,可以找到无法解答的原因)。在这种情况下,使用对象构造结果。

所以在这种情况下,将你的功能改为例如

static final double threshold = 0.000001;

//finds root; returns null if none is found
static Double findaroot(double x1, double x2)
{
    if(  Math.signum( f(x1,0) ) == Math.signum( f(x2,0) )  )
    {
        return null;
    }
    else
    {
        if(Math.abs(x1-x2)<=threshold)
        {
            return x1;
        }
        else
        {
            return Math.min( findaroot(x1,(x1+x2)/2) , findaroot((x1+x2)/2,x2));
        }
    }
}