栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

2种方法求解根号2

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2种方法求解根号2

文章目录
  • 前言
  • 一、牛顿-拉弗森法(Newton-Raphson Method)
  • 二、二分查找法(Binary Search)
    • 1.算法原理
    • 2.Python实现
  • 三、两种算法的效率比较
  • 总结


前言

这是一道经典的面试题:自己编写函数实现根号2(根号n)的求解。排除显然答案:

from math import sqrt
print(sqrt(2))
一、牛顿-拉弗森法(Newton-Raphson Method)

这个方法被认为同时被艾萨克·牛顿和约瑟夫·拉弗森提出,所以名为牛顿-拉弗森法。

结论:如果存在一个k是多项式p的根的有效近似,那么k - p(k) / p’(k)就是一个更有效的近似值。其中p’是p的一次导数。

求解根号n可以转化为求多项式x ^ 2 - n的根的问题,该多项式的一次导数是2x. 因此,如果当前的猜测是k, 那么可以选择k - (k ^ 2 - n) / 2k 作为下一个猜测值,直到误差(k ^ 2 - n)的绝对值小于给定的值epsilon. 这种方法称为逐次逼近。

Python实现:

# 利用牛顿-拉弗森法寻找平方根
# 寻找x,满足x ^ 2 - k 在 (0, epsilon)范围内

def newton_raphson(k, epsilon):
    guess = k
    while abs(guess * guess - k) >= epsilon:
        guess = guess - (((guess * guess) - k) / (guess * 2))
    return guess


print(newton_raphson(2, 0.000000001))
二、二分查找法(Binary Search) 1.算法原理

如果x是大于1的数,则根号x一定位于0到x之间,此时我们用(暴力的)二分查找法求根号x的近似值,判定迭代结束的条件为abs(ans ^ 2 - x) < epsilon.

如果x是小于1大于0的数,则根号x位于0到1之间,此时我们在(0,1)区间内用二分查找法求解根号x的近似值,迭代结束的条件同上。

2.Python实现

注意由于没有事先判定x的范围,所以查找上限变成了max(1.0, x). 下限为0.

# 使用二分查找求近似平方根

def bi_search_root(x, epsilon):
    low = 0.0
    high = max(1.0, x)
    ans = (high + low) / 2.0
    while abs(ans ** 2 - x) >= epsilon:
        if ans ** 2 < x:
            low = ans
        else:
            high = ans
        ans = (high + low) / 2.0
    return ans


print(bi_search_root(2, 0.000000001))
三、两种算法的效率比较

从时间复杂度上来看,牛顿法优于二分查找法。
我们可以对之前的代码进行简单的修改,以直观地看出这一区别:
将牛顿-拉弗森法的代码修改为:

# 利用牛顿-拉弗森法寻找平方根
# 寻找x,满足x ^ 2 - k 在 (0, epsilon)内

def newton_raphson(k, epsilon):
    guess = k / 2.0
    times = 0
    while abs(guess * guess - k) >= epsilon:
        guess = guess - (((guess * guess) - k) / (guess * 2))
        times += 1
    return guess, times


print(newton_raphson(2, 0.000000001))

times变量用于记录迭代求解的总次数。这里和以下的二分查找法的epsilon参数均设置为0.000000001.
将二分查找法的代码修改为:

# 使用二分查找求近似平方根

def bi_search_root(x, epsilon):
    numGuesses = 0
    low = 0.0
    high = max(1.0, x)
    ans = (high + low) / 2.0
    while abs(ans ** 2 - x) >= epsilon:
        numGuesses += 1
        if ans ** 2 < x:
            low = ans
        else:
            high = ans
        ans = (high + low) / 2.0

    return ans, numGuesses


print(bi_search_root(2, 0.000000001))

numGuesses变量用于记录迭代求解的总次数。
运行结果:牛顿法只用了四次迭代就得到了满意的近似值,而二分查找法则需要29次才能得到类似的结果。

(1.4142135623746899, 4)
(1.4142135623842478, 29)
总结

本文介绍了两种自定义求解根号的方法(Python实现),分别是牛顿-拉弗森法和二分查找法。牛顿-拉弗森法的时间复杂度比简单二分查找要低。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/993914.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号