返回

用心学习,笨鸟都能变凤凰

闲谈

大家好,日拱一卒,我是梁唐。本文始发于公众号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] 之间。我们可以通过以下步骤来求解:

  1. 计算中点 x_m = (a + b) / 2。
  2. 计算 f(x_m)。
  3. 如果 f(x_m) = 0,则 x_m 是方程根。
  4. 如果 f(x_m) 和 f(a) 异号,则方程根在 [a, x_m] 之间,否则方程根在 [x_m, b] 之间。
  5. 重复步骤 1-4,直到方程根收敛到某个精度。

对于本题,我们可以将 f(x) 定义为:

f(x) = x^3 + cr^2 - 2

那么,我们只需要找到一个区间 [a, b],使得 f(a) 和 f(b) 异号即可。

综合方法

对于本题,我们可以使用如下方法来求解:

  1. 如果 c = 0,使用牛顿法求解。
  2. 如果 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 的值来选择合适的方法求解。

通过这道题,我们学习了牛顿法和二分法的原理和应用,也锻炼了我们的代码实现能力。希望大家能够举一反三,将这些方法应用到其他问题中去。


相关文章