算法题:求正实数x的平方根 (注意不是整数)& 求方程的根

算法题:求正实数x的平方根

69. x 的平方根

不同于LC69,面试题要求x是正实数,而不是整数。并且需要注意x可能是小数,此时x的平方根是大于x的

二分法

https://blog.csdn.net/weixin_27625589/article/details/116221090

copy
def mySqrt2(x): # 正实数x的平方根,注意是实数、注意可能是正的小数 left = 0 right = max(x, 1.0) # x是正小数的情况下,平方根比x大,但肯定是小于1.0的 while left < right: mid = (left + right) / 2.0 # 实数 # print(left, right, mid, mid * mid) if abs(mid * mid - x) < 1e-6: # 精度 return mid if mid * mid > x: right = mid # 实数,不是mid-1 elif mid * mid < x: left = mid print(mySqrt2(10), mySqrt2(0.09)) # 3.162277638912201 0.2999992370605469

梯度下降法

https://leetcode-cn.com/problems/sqrtx/solution/bu-chong-yi-ge-ti-du-xia-jiang-fa-by-tra-fkds/
!image

copy
import math class Solution: # 请注意,此处的参数原题是 x, # 为了更好理解改为了 t, 而 x 用于迭代过程,和公式相匹配 def mySqrt(self, t: int) -> int: # 初始值,注意,初始值不能设为0,否则所有迭代结果均为0 x = 1 # 定义学习率 learning_rate = 0.00001 # 定义精度 eps = 1e-5 while math.fabs(x ** 2 - t) > eps: # 梯度下降迭代过程 x = x - learning_rate * self.gradient(x, t) # res = int(x) # # 注意边界值,因为 int 会向下取整,所以需判断 int+1 是否更接近答案 # return (res + 1) if (res+1)**2 <= t else res return x # 返回实数,不要取整 def gradient(self, x, t): return 4 * x * (x ** 2 - t) s = Solution() print(s.mySqrt(0.09)) # 0.30001666619774

假如现在要求的是根号2 即 x2=2 的解 使用梯度下降法,梯度下降主要通过求梯度为0的点,得到凸函数的全局最小值 x2 是凸函数。首先构建损失函数为凸函数的目标函数, 使得目标函数的最小值对应的是我们要求的值

x2=t:逼近t的损失函数是 L=(x2t)2, 对x求梯度是:dL/dx=4x(x2t)

copy
def gradient_descent(n): x = float(random.randint(1, 100)) array = [] # 保存每一步的估计 while (abs(x ** 2 - n) > 0.0001): # 精度是0.0001, 也可以使用梯度绝对值不接近0作为继续循环的条件 x = x - 0.00001 * 4 * x * (x ** 2 - n) # 学习率是0.00001, array.append(x) return array n=10 array = gradient_descent(n) # x = range(len(array)) # plt.plot(x, array, color='b') # plt.show() import math print(math.sqrt(n), array[-1])

牛顿法

https://blog.csdn.net/dpengwang/article/details/99092278

https://blog.csdn.net/songyunli1111/article/details/90474836

image

copy
import random import matplotlib.pyplot as plt import math def Newton(n): # target array = [] # 保存每一步估计 x = float(random.randint(1, 100)) # 随机初始点 while(abs(x**2 - n) > 0.000000001): # 精度, 也可以使用梯度绝对值不接近0作为继续循环的条件 x = x - (x**2 - n ) / (2*x) # 牛顿法公式 array.append(x) return array n=10 array = Newton(n) # x = range(len(array)) # plt.plot(x, array, color='b') # plt.show() print(math.sqrt(n), array[-1])

补充:数值计算方法:二分法求解方程的根

https://blog.csdn.net/weixin_27625589/article/details/116221090

copy
def fun(x): return x ** 2 + x - 6 def newton(a,b,e): # e 是 精度 x = (a + b)/2.0 if abs(b-a) < e: return x else: if fun(a) * fun(x) < 0: return newton(a, x, e) else: return newton(x, b, e) print(newton(-5, 0, 5e-5)) print(newton(0, 5, 5e-5)) # -3.000011444091797 # 1.9999885559082031
copy
# 二分法求解方程的根 def fun(x): return x ** 2 + x - 6 def binSearch(a, b): # 当 fun(a), fun(b)异号,且设只有一个根的时候 left, right = a, b while left <= right: mid = (left + right) / 2.0 if abs(fun(mid)) < 1e-6: return mid if fun(mid) * fun(left) < 0: # left和mid的函数值异号 right = mid else: left = mid print(binSearch(-5, 0), "\n", binSearch(0, 5)) # -3.0000001192092896 # 1.9999998807907104
posted @   麦克斯的园丁  阅读(280)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
🚀