Algorithm 多项式求根二分法

Algorithm 多项式求根二分法,algorithm,math,bisection,Algorithm,Math,Bisection,如果我用二分法求多项式的根,在某些情况下,根据多项式的不同,根可能是负的,也可能是正的 我知道我可以根据多项式的求值结果来确定根是负的还是正的。。。然而,我不确定我会用什么作为x 有人能给出一些见解吗?根可以是负的,也可以是正的,这与二分法无关。根的存在可以用微积分中的公式来证明 所以你所要做的就是找到点x1和x2,这样y(x1)是负的,y(x2)是正的。然后从IVT中知道x1和x2之间有一个根。您可以通过在该时间间隔上进行二进制搜索来实现这一点。如果y(x3)=y((x1+x2)/2)为负,则

如果我用二分法求多项式的根,在某些情况下,根据多项式的不同,根可能是负的,也可能是正的

我知道我可以根据多项式的求值结果来确定根是负的还是正的。。。然而,我不确定我会用什么作为x


有人能给出一些见解吗?

根可以是负的,也可以是正的,这与二分法无关。根的存在可以用微积分中的公式来证明

所以你所要做的就是找到点
x1
x2
,这样
y(x1)
是负的,
y(x2)
是正的。然后从IVT中知道
x1
x2
之间有一个根。您可以通过在该时间间隔上进行二进制搜索来实现这一点。如果
y(x3)=y((x1+x2)/2)
为负,则在间隔
[x3,x2]
上重复对分搜索。否则,如果为正值,则搜索间隔
[x1,x3]


根是负是正并不重要。我不确定这是否回答了您的问题,但我希望这有助于您理解算法。

许多根查找器允许用户提供一个或多个开始搜索的点。这允许用户尝试“摆弄”结果以找到不同的根,或者允许查找器收敛到根

如果允许用户提供起始值是没有意义的,您可以从探测几个点开始:

  • -1,0,1
  • -10,0,10
  • -100,0,100
  • 等等
如果输入是一个奇数多项式,这将最终发现一个合适的二分法范围。如果输入是一个偶数多项式,那么您可能永远不会捕捉到符号变化(考虑f(x)=x^2——它永远不会是负数),因此在经过一定量的(可配置的?)探测后,请准备放弃

我建议把范围扩大10倍;由于二分法每次都将范围减半,这可能太保守了。(需要两到三次对分迭代才能将范围缩小到下一个“更紧”的括号中。)可能更好的方法是更大的跳跃:

  • -10,0,1
  • -1000,0,1000
  • -10万,0,10万
  • 等等

这将执行更少的探测,但需要更多的二分法。尝试一些多项式,并跟踪执行时间,以找到两个建议的根。

为了使用对分算法,首先需要找到一个包含根的区间。中给出了这方面的标准算法


然而,标准的对分算法期望端点中函数值的符号不同。这可能是个问题。最简单的例子是x^2,它的单根0的阶数为2。由于x^2对于所有非零x都是正的,因此您无法找到一个包含根的区间,该区间适用于二分法。

您可能会发现这很有帮助

使用制度

名称空间二分法

{

类程序
{
公共双中点(双xl,双xu)
{
返回(xl+xu)/2;
}
公共双功能(双x)
{
返回(x*x-2);
}
静态void Main(字符串[]参数)
{
程序根=新程序();
双xm=0,xl=1,xu=2,check=0;
对于(int x=0;x<20;x++)
{
xm=(xl+xu)/2;
检查=根函数(xl)*根函数(xm);
如果(检查<0)
xu=xm;
否则如果(检查>0)
xl=xm;
否则如果(检查==0)
{
打破
}
}
WriteLine(“根的近似值为{0}”,xm);
}
}
}


这类问题听起来更适合Math.SE,甚至SciComp.SE。当然,并非所有多项式都有(实)根;e、 g.,1+x^2。还有一些具有实根的多项式(例如x^2)永远不会改变符号。通常不建议使用仅链接的答案。仅链接的答案很脆弱,因为链接可能会断开。请详细说明链接。这是完整的程序!
class Program

{

    public double midPoint (double xl, double xu)

{

    return (xl + xu) / 2;

}

    public double function(double x)

    {

        return (x*x-2);

    }

    static void Main(string[] args)

    {

        Program root = new Program();

        double xm=0, xl=1, xu=2, check=0;

        for (int x = 0; x < 20; x++)

        {

            xm = (xl + xu) / 2;

            check = root.function(xl) * root.function(xm);

            if (check < 0)

                xu = xm;

            else if (check > 0)

                xl = xm;

            else if (check == 0)

            {

                break;

            }

        }

        Console.WriteLine("The Approximate of the Root is {0}", xm);

    }

}