牛顿迭代法

牛顿迭代法(Newton’s method)又称为牛顿-拉夫逊(拉弗森)方法。假设 r 是 f(x)=0 的一个根,我们随便选择一个值 x_0,过点 (x_0,f(x_0)) 做曲线 f(x) 的切线 L1 ,那么 L1 的斜率就是 f'(x_0) ,如下图所示:


假设一个曲线的函数是 f(x) ,过点 (x_0,f(x_0)) 做曲线 f(x) 的切线为 L1 ,那么 L1 与 x 轴的交点为 x_1 ,我们来计算一下 x_1 的值。


通过上面的计算我们知道,切线 L1 与 X 轴的交点为 x_1=x_0-f(x_0)/f'(x_0) ;然后我们再以 x_1 为横坐标,过点 ( x_1,f( x_1)) 做曲线 f(x) 的切线 L2 ,通过计算我们可以得到 L2 与 x 轴的交点 x_2=x_1-f(x_1)/f'(x_1),我们继续过点 (x_2,f(x_2)) 再做切线 …… ,一直这样重复下去,计算的次数越多 x_n 就越接近 f(x)=0 的一个解。

假设我们需要求数字 num 的一个平方根,令 f(x)=x^2-num,对 f(x) 求导,得到 f'(x)=2*x ;代入上面公式可以得到 x1=x-(x^2-num)/2x ,整理得到 x1=(x+num/x)/2 ,这个就是牛顿迭代法手动开根公式,假设 num 等于 2 ,我们来看下求更号 2 该怎么计算,刚开始的时候我们会随便选择一个数字 x_0 ,假设选的很离谱比如 10 ,来看下计算结果:

第1次:x0=10,计算x1=(10+2/10)/2=5.1
第2次:x1=5.1,计算x2=(5.1+2/5.1)/2=2.746078431372549
第3次:x2=2.746078431372549,计算x3=1.7371948743795984
第4次:x3=1.7371948743795984,计算x4=1.4442380948662321
第5次:x4=1.4442380948662321,计算x5=1.4145256551487377
第6次:x5=1.4145256551487377,计算x6=1.4142135968022693
第7次:x6=1.4142135968022693,计算x7=1.4142135623730954

我们知道 2 的平方根是 1.4142135623730951 ,当计算到第 7 次的时候就已经非常接近了,所以即使刚开始选的数字很离谱,经过几次计算之后,结果也是非常接近答案的,下面来看下代码。

/**
 * @param num   求数字num的平方根,
 * @param count 循环的次数
 * @return
 */
public static double sqrt(double num, int count) {
    double res = 10;
    for (int i = 0; i < count; i++)
        res = (res + num / res) / 2;
    return res;
}

来举几个例子测试下。

public static void main(String[] args) {
    double num = 10;// 计算10的平方根
    System.out.println("官方计算的结果:" + num + "的平方根是" + Math.sqrt(num));
    System.out.println("我们计算的结果:" + num + "的平方根是" + sqrt(num, 10));
    System.out.println();
    num = 13.75;// 计算13.75的平方根
    System.out.println("官方计算的结果:" + num + "的平方根是" + Math.sqrt(num));
    System.out.println("我们计算的结果:" + num + "的平方根是" + sqrt(num, 10));
}

看一下运行结果:

官方计算的结果:10.0的平方根是3.1622776601683795
我们计算的结果:10.0的平方根是3.162277660168379

官方计算的结果:13.75的平方根是3.7080992435478315
我们计算的结果:13.75的平方根是3.7080992435478315

信奥赛编程(刷题请进)>>>

经过两年的打磨,我的新作《算法秘籍》已经出版,有需要的可以点击购买。也可以点击 内容介绍 查看详情。