用心学习,笨鸟都能变凤凰
2024-02-25 05:41:41
大家好,日拱一卒,我是梁唐。本文始发于公众号Coder梁(戳我)。
今天我们继续来看伯克利CS61A,我们来看作业5的最后一道附加题。这道题非常有意思,涉及很多知识,因此想要完整讲明白,需要很多篇幅,所以单独写一篇文章来聊聊。
这道题是:
给定一个实数 x 和一个常数 c,求一个实数 r,使得:
r^3 + cr^2 - 2 = 0
如果 c = 0,使用牛顿法求解。如果 c != 0,使用二分法求解。
牛顿法
牛顿法是一种求解方程根的方法,它的原理是:
如果我们有一个函数 f(x) = 0,我们可以通过以下公式来逼近它的根:
x_{n+1} = x_n - f(x_n) / f'(x_n)
其中,x_n 是当前的逼近值,x_{n+1} 是下一个逼近值,f(x_n) 是函数值,f'(x_n) 是导数值。
对于本题,我们可以将 f(x) 定义为:
f(x) = x^3 + cr^2 - 2
那么,它的导数为:
f'(x) = 3x^2 + 2cr
将 f(x) 和 f'(x) 代入牛顿法的公式中,我们可以得到:
x_{n+1} = x_n - (x_n^3 + cr_n^2 - 2) / (3x_n^2 + 2cr_n)
其中,x_n 是当前的逼近值,x_{n+1} 是下一个逼近值,c 是常数,r_n 是 x_n 的平方。
二分法
二分法是一种求解方程根的方法,它的原理是:
如果我们有一个函数 f(x) = 0,且我们知道 f(a) 和 f(b) 异号,那么方程根一定在 [a, b] 之间。我们可以通过以下步骤来求解:
- 计算中点 x_m = (a + b) / 2。
- 计算 f(x_m)。
- 如果 f(x_m) = 0,则 x_m 是方程根。
- 如果 f(x_m) 和 f(a) 异号,则方程根在 [a, x_m] 之间,否则方程根在 [x_m, b] 之间。
- 重复步骤 1-4,直到方程根收敛到某个精度。
对于本题,我们可以将 f(x) 定义为:
f(x) = x^3 + cr^2 - 2
那么,我们只需要找到一个区间 [a, b],使得 f(a) 和 f(b) 异号即可。
综合方法
对于本题,我们可以使用如下方法来求解:
- 如果 c = 0,使用牛顿法求解。
- 如果 c != 0,使用二分法求解。
具体实现如下:
def find_root(c, x0, tol=1e-6):
"""Finds the root of the equation x^3 + cr^2 - 2 = 0.
Args:
c: The constant c.
x0: The initial guess for the root.
tol: The tolerance for the solution.
Returns:
The root of the equation.
"""
if c == 0:
return newton_method(lambda x: x**3 - 2, lambda x: 3*x** 2, x0, tol)
else:
return bisection_method(lambda x: x**3 + c*x** 2 - 2, -100, 100, tol)
def newton_method(f, fprime, x0, tol=1e-6):
"""Finds the root of a function using Newton's method.
Args:
f: The function to find the root of.
fprime: The derivative of the function.
x0: The initial guess for the root.
tol: The tolerance for the solution.
Returns:
The root of the function.
"""
x = x0
while abs(f(x)) > tol:
x -= f(x) / fprime(x)
return x
def bisection_method(f, a, b, tol=1e-6):
"""Finds the root of a function using the bisection method.
Args:
f: The function to find the root of.
a: The lower bound of the interval.
b: The upper bound of the interval.
tol: The tolerance for the solution.
Returns:
The root of the function.
"""
while abs(b - a) > tol:
m = (a + b) / 2
if f(m) == 0:
return m
elif f(m) * f(a) < 0:
b = m
else:
a = m
return (a + b) / 2
总结
牛顿法和二分法是求解方程根的两种常用方法,它们各有优缺点。牛顿法收敛速度快,但需要计算导数,二分法收敛速度慢,但不需要计算导数。对于本题,我们可以根据 c 的值来选择合适的方法求解。
通过这道题,我们学习了牛顿法和二分法的原理和应用,也锻炼了我们的代码实现能力。希望大家能够举一反三,将这些方法应用到其他问题中去。