简体   繁体   English

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

[英]How to roll back on a recursive function that returns specific values

Hello and thank you for your time and support. 您好,感谢您的宝贵时间和支持。

My generalized question is: How should one roll back in a recursive function where specific values have to be returned? 我的普遍性问题是:在必须返回特定值的递归函数中,应该如何回滚?

My specific case: 我的具体情况:

In this problem, I have to check whether a given polynomial has any roots in a given interval, defined by it's margins: x1 and x2. 在这个问题中,我必须检查给定的多项式在给定的间隔内是否有任何根,由其边距定义:x1和x2。

I have to do this by continuously halving the interval [x1,x2] until the difference between them is at most a value close to zero (for this value, I used the foundroot variable), in which case a root has been found. 为此,我必须连续地将间隔[x1,x2]减半,直到它们之间的差最大为接近零的值(对于该值,我使用foundroot变量),在这种情况下,已经找到了根。

This process is done by the recursive findaroot method with parameters x1 and x2 (the interval margins). 此过程由带有参数x1和x2(间隔边距)的递归findaroot方法完成。

Here is how the method works: 该方法的工作原理如下:

  1. The method first checks whether the value for f(x1) and f(x2) (the function's values in x1 and x2) have the same sign, in which case, there is no root in the interval, and returns the noroot value; 该方法首先检查f(x1)f(x2)的值(x1和x2中函数的值)是否具有相同的符号,在这种情况下,区间中没有根,并返回noroot值;

  2. Then , it checks whether a root has been found (if x1 - x2 <= foundroot ); 然后,它检查是否已找到根(如果x1 - x2 <= foundroot );

  3. If a root has not been found, it returns minimum between the returned values for one of the intervals, noroot being a very high number in my case. 如果未找到根,则它会在一个间隔中返回最小的返回值,在我的情况下, noroot是一个非常高的数字。 Of course, this doesn't work if a root exceeds the value of noroot . 当然,如果root超过noroot的值,则此方法不起作用

My question is: 我的问题是:

  • As the generalized question states, how should I make the method work for all cases, other than comparing the returned value with a high/low/not-easily-obtained number? 如一般性问题所述,除了将返回值与高/低/不易获得的数字进行比较之外,我应如何使该方法适用于所有情况?

Here is my written code: 这是我的书面代码:

    //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));
            }
        }
    }

If there's anything unclear, please ask. 如果不清楚,请询问。 If you believe my questions/title are unspecific or unclear, please tell me how to modify them. 如果您认为我的问题/标题不确定或不清楚,请告诉我如何修改它们。

I will make clarifications as best I can to provide a clear description and, hopefully, a clear answer. 我将尽力澄清,以提供清晰的描述,并希望给出清晰的答案。

Thank you! 谢谢!

Using a magic number (no root), can be avoided by using a meaningful return value. 通过使用有意义的返回值可以避免使用幻数(无根)。 In this case, you could consider switching to Double instead of double, and using the null value as a "no result" indicator. 在这种情况下,您可以考虑切换为Double而不是double,并将空值用作“无结果”指示符。

This can be applied generically: If you are using recursive functions to calculate a certain outcome, but need to escape as well, using the null value is an acceptable escape. 这可以一般性地应用:如果您使用递归函数来计算某个结果,但是还需要转义,则使用null值是可以接受的转义。 You could consider compound answers as well in case you need more than 1 escape (eg the reason for deciding no answer can be found). 如果您需要1个以上的转义,也可以考虑使用复合答案(例如,找不到答案的原因)。 Use an object to construct your result in that case. 在这种情况下,使用对象构造结果。

So in this case, alter your function to eg 因此,在这种情况下,请将您的功能更改为

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));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM