算法基础: 牛顿迭代法

算法基础: 牛顿迭代法

序言:
本文记录用牛顿迭代法求高阶方程的解。

0. 概述
给定函数 f ( x ) f(x) f(x), 则 f ( x ) = 0 f(x) = 0 f(x)=0 的解可以通过牛顿迭代法逼近。本文只记录方法,不深究原理。迭代步骤如下:

  1. f ( x ) f(x) f(x) 上一点 x n x_n xn 作为迭代起点。
  2. x n x_n xn f ( x ) f(x) f(x) 的切线,交 x x x 轴于 x n + 1 x_{n+1} xn+1
  3. 重复步骤 1,2, 直到 f ( x ) − 0 &lt; ϵ f(x) - 0 &lt; \epsilon f(x)0<ϵ

1. x x x 的平方根(LintCode 69)
问题描述:实现 int sqrt(int x) 函数,计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

求解 t = x t = \sqrt{x} t=x 等价于 t 2 − x = 0 t ^ 2 - x= 0 t2x=0。命 f ( t ) = t 2 − x f(t) = t^2 - x f(t)=t2x, 其零点即为所求。
设迭代起点为 t 0 t_0 t0, 则 f ( t ) f(t) f(t) t 0 t_0 t0 的切线 f ′ ( t 0 ) ( t − t 0 ) = y − f ( t 0 ) f&#x27;(t_0)(t - t_0) = y - f(t_0) f(t0)(tt0)=yf(t0),其交 x x x 轴于
t 1 = ( t 0 + x t 0 ) / 2 t_1 = (t_0 + \frac{x}{t_0}) /2 t1=(t0+t0x)/2
继续对 t 1 t_1 t1 进行迭代,直到某个 t n t_n tn 满足 t n 2 ≤ x t_n^2 \le x tn2x ( t n + 1 ) 2 &gt; x (t_n + 1)^2 &gt; x (tn+1)2>x 即可

  • C++ 实现
class Solution {
public:
    int mySqrt(long x) {
        if (x == 0) return 0;
        long t = x; // t: 迭代变量,初始化为 x 
        while(true){
            t = (t + x / t) / 2;
            if (t * t <= x && (t + 1) * (t + 1) > x) 
                return t;
        }
        return -1;
    }
};

2. x x x 的立方根
问题描述:计算并返回 x 的立方根, 误差不大于10e-9。

求解 t = x 3 t = \sqrt[3]{x} t=3x 等价于 t 3 − x = 0 t ^ 3 - x= 0 t3x=0。命 f ( t ) = t 3 − x f(t) = t^3 - x f(t)=t3x, 其零点即为所求。
设迭代起点为 t 0 t_0 t0, 则 f ( t ) f(t) f(t) t 0 t_0 t0 的切线 f ′ ( t 0 ) ( t − t 0 ) = y − f ( t 0 ) f&#x27;(t_0)(t - t_0) = y - f(t_0) f(t0)(tt0)=yf(t0),其交 x x x 轴于
t 1 = ( 2 t 0 + x t 0 2 ) / 3 t_1 = (2t_0 + \frac{x}{t_0^2}) / 3 t1=(2t0+t02x)/3
继续对 t 1 t_1 t1 进行迭代,直到某个 t n t_n tn 满足 ∣ t n 3 − x ∣ ≤ 1 0 − 9 \vert{t_n^3 - x}\vert \le 10^{-9} tn3x109

  • C++ 实现
#include <iostream>

using namespace std;
const double eps = 10e-9;
class Solution {
public:
    double myCbrt(double x) {
        if (x == 0) return 0;
        double t = x; // t: 迭代变量,初始化为 x
        while(t * t * t - x >= eps || t * t * t - x <= -eps) {
            t = (2 * t + x / t / t) / 3;
            cout << t << endl; // 打印迭代变量
        }
        return t;
    }
};

int main() {
    Solution s;
    cout << s.myCbrt(-100) << endl;
    return 0;
}

???
ajaxlt的GitHub入口: https://github.com/ajaxlt/OnlineProgram
???

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值