前言

前几天刷题时候看到一道题,就是不用任何内置函数与库,实现算一个数的根,第一反应就是二分法,后面在一众评论和题解中发现一个方法,叫做牛顿迭代,还蛮有意思的,下面,我们就一起来看一下牛爵爷的方法。

牛顿迭代解释

牛顿 迭代法 (Newton’s method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method),它是 牛顿 在17世纪提出的一种在 实数 域和 复数 域上近似求解方程的方法。 多数方程不存在求根公式,因此求精确根非常困难,甚至不可解,从而寻找方程的近似根就显得特别重要。 方法使用函数 的 泰勒级数 的前面几项来寻找方程 的根。 牛顿迭代法是求方程根的重要方法之一,其最大优点是在方程 的单根附近具有平方收敛,而且该法还可以用来求方程的重根、复根,此时线性收敛,但是可通过一些方法变成 超线性收敛 。
这是网上的解释,说实话,我觉得这个说来就算我再看十遍也看不明白。于是我花了时间找了很多博主写的文章与代码,总算对这个东西有了个浅显的理解(奈何笔者高数成绩不怎么样,无法像网上众多大佬一样对其进行化简)

牛顿迭代原理

牛顿迭代方程:x(n+1)=xn - f(xn)/f’(xn)

如图所述,实际上就是根据一个初始点做切线,找到该切线与X轴的交点,找到下一个点的坐标,然后不断的迭代,直到找到误差最小的点为止。

pytorch 牛顿法 海森矩阵 牛顿迭代python_算法


(图片来源网络,侵删)

意思就是,你知道一个离根很近的X的坐标xn,并且知道该函数的导数,那么就可以找到下一个离根更近的点,这个点不是该方程的解,只是不断的靠近它,我们找到一定误差范围内的就行了。

力扣题

那么,说了那么多,跟我们的python算法有何关系呢?且让我们回到开头所说的题目上面,我们先看题:

pytorch 牛顿法 海森矩阵 牛顿迭代python_pytorch 牛顿法 海森矩阵_02


力扣链接 除此题外,第367题也是:

pytorch 牛顿法 海森矩阵 牛顿迭代python_牛顿迭代_03

力扣链接

python实现

那么就正式上代码:

#牛顿迭代
class Solution:
    def mySqrt(self, x: int) -> int:
        val=1
        while True:
            val=val-(val*val*val-x)/(3*val*val)
            if val*val*val - x <0.0001:
                break
        val=int(val)
        return val

我们先用立方根试试看:

print(Solution().mySqrt(27))

输出:

pytorch 牛顿法 海森矩阵 牛顿迭代python_pytorch 牛顿法 海森矩阵_04


结果正常,那么就改成题目要的平方根,来解一下题:

#牛顿迭代
class Solution:
    def mySqrt(self, x: int) -> int:
        val=1
        while True:
            val=val-(val*val-x)/(2*val)
            if val*val - x <0.0001:
                break
        val=int(val)
        return val

pytorch 牛顿法 海森矩阵 牛顿迭代python_牛顿迭代_05


结果也还行,也算实现了一题多解(自我安慰一下)。

附(二分法解此题(力扣367))

class Solution:
    def isPerfectSquare(self, num: int) -> bool:       
        left ,right = 0, num
        while right >= left:
            mid=(left+right)//2
            sq=mid*mid
            if sq == num:
                return True
            if sq > num:
                right=mid - 1
            else:
                left=mid + 1
        return False

二分法结果如下:

pytorch 牛顿法 海森矩阵 牛顿迭代python_leetcode_06


算法初学者,小白一枚,如有纰漏的地方,希望评论斧正,感激不尽。