原谅我标题党了,牛顿迭代法不是万能的,但是它能解决工程上95%的解方程问题。
可能有人要问了,一元方程还用解?口算一下不就出来了!
但如果是x^5 +x^4 +x^3=100这种一元多次方程,就不是口算的问题了,笔算也算不出来。
五次及以上多项式方程没有根式解(就是没有像二次方程那样的万能公式),这个是被伽罗瓦用群论做出的最著名的结论。
但是没有根式不代表没有办法求解,牛顿迭代法就是通过迭代的方式,不断逼近正确解的万金油方法,并且,它在程序上非常好实现!
其方法是:取一个初始点,在该点做函数的切线,并以切线与x轴的交点作为下一个初始点,继续做切线……函数会很快收敛到零点附近。
取A点作为初始点,可以看到,四次迭代之后,就很接近函数的根了。
切线很好求,交点也很好求,我们可以简单推导出这样一个表达式:
然后就是代码实现。
做切线也就是求函数的导数,因此我们首先要做两件事:
- 将函数用程序表示出来
- 将函数的导数用程序表示出来
例如,x^4 +x^3-100=0这个函数,用笔算很难求解:
求出其导数为:4x^3 +3x^2=0
用代码表示出来:
然后,定义一个方法来进行迭代,方法的入参为(初始值,容许的最大精度,最大迭代次数):
设定初始值为1,精度为0.00000001,跑一下试试:
可以看到,9次迭代之后,精度就已经达到了6e-9,得出的结果为2.9390275687304728,把它代入原函数试一下:
结果为:
由于精度问题,就直接显示为0了,说明迭代出来的结果非常接近函数的根了,而我们想要的话完全可以调到更高的精度,求解完成!
由于实现的难度很低(唯一难点是将函数导数求出来,并且用代码表示),而由于其涉及导数,逼近的速度也不是简单的一次逼近,而是接近次方的速度,
因此时间复杂度也很低,消耗不大。
综上所述,牛顿迭代法在工程领域有相当广泛的应用,尤其在解复杂函数中尤为有效,犹如一把刺入黄油的尖刀。
但是,牛顿迭代法处理不了以下几种函数,先看定义:
牛顿迭代法收敛的充分条件:若f二阶可导,那么在待求的零点x周围存在一个区域,只要起始点x_{0}位于这个邻近区域内,那么牛顿-拉弗森方法必定收敛。
也就是说,错误初值的选择可能会导致解不收敛。
例如:
起始点不幸选择了驻点,在几何意义上该点切线根本没有根。
函数 x^(1/3):越迭代只会越远离零点。
|x|^(1/2):循环震荡,永远在那几个点波动。
有多个解的函数,会导致只能迭代出最近的那个根,而如果我们要的是另一个跟,就需要好好商榷初值的位置了。
因此牛顿迭代法虽然好用,但是也有几点需要注意:
1. 初值的选择
2. 迭代范围的选择
因为大多数的不规则函数,可以在某个区间近似为规则的,而我们业务上一般需要求的值都在某个区间内,规定了区间,
并确定在这个区间有解的话,就可以放心大胆的使用牛顿迭代法了。
参考:https://blog.csdn.net/ccnt_2012/article/details/81837154