牛顿迭代法求根C++
2019-12-26 本文已影响0人
小pb
题目描述:
计算一个数字的立方根,不使用库函数
首先最常见的方法是二分法进行求值,这里主要注意精度,还有就是二分法的求值,但是这种方法有时候不满足题目给的时间复杂度的要求,那么需要一种新的方法来进行求值。
所以这里给出牛顿迭代法:
牛顿迭代法
这里应该大学都知道,一个函数f(x) = x^3-y 的可以在坐标系上画出它的图。
牛顿迭代法.png
随便找一个曲线上的A点(为什么随便找,根据切线是切点附近的曲线的近似,应该在根点附近找,但是很显然我们现在还不知道根点在哪里),做一个切线,切线的根(就是和x轴的交点)与曲线的根,还有一定的距离。牛顿、拉弗森们想,没关系,我们从这个切线的根出发,做一根垂线,和曲线相交于B点,继续重复刚才的工作:
牛顿迭代法2.png之前说过,B点比之前A点更接近曲线的根点,牛顿、拉弗森们很兴奋,继续重复刚才的工作:
经过多次迭代后会越来越接近曲线的根(下图进行了50次迭代,哪怕经过无数次迭代也只会更接近曲线的根,用数学术语来说就是,迭代收敛了):
众所周知,f'(x) 是f(x)的导数,也是在某点上的一个切线方程。
牛顿它们根据上面的方法,不断的逼近根的方法,可以总结为以下的表示方法。
Xn+1 = Xn - f(Xn)/ f'(Xn)
从而对于求立方根的时候,我们可以假设
f(x) = X^3 - y
求y的立方根表示, f(x)=0的时候,求x的值这样的数学模型。
根据上面的公式,我们可以得到
Xn+1 = Xn- (Xn^3 -y)/(3*Xn^2) = (2*Xn +y/(Xn*Xn))/3
根绝这里的公式,我们就可以写出立方根的解法了。
#include <iostream>
using namespace std;
// 牛顿迭代法
// f(x) = X^3 - y, 当f(x) =0时,求x
// 根据牛顿迭代法。Xn+1 = Xn - f(Xn)/ f'(Xn)
// 所以 xn+1 = x- (X^3 -y)/(3X^2) = X*2/3 + y/(*X^2) * 1/3
// Xn+1 = (X)/3
inline double abs(double x){return (x>0?x:-x);}
double getcudeRoot(double y) {
double x =1.0;
for (x = 1.0; abs(x*x*x -y) > 1e-6; x=(2*x+y/x/x)/3);
return x;
}
int main() {
double input;
while (cin >> input) {
printf("%.1f\n", getcudeRoot(input));
}
return 0;
}
参考:
牛顿迭代法