Python算法100例-1.3 牛顿迭代法求方程根

完整源代码项目地址,关注博主私信’源代码’后可获取

1.问题描述

编写用牛顿迭代法求方程根的函数。方程为 a x 3 + b x 2 + c x + d = 0 ax^3+bx^2+cx+d=0 ax3+bx2+cx+d=0,系数a、b、c、d由主函数输入,求x在1附近的一个实根。求出根后,由主函数输出。

牛顿迭代法的公式: x = x 0 − f ( x ) f ′ ( x 0 ) x=x_0-\frac{f(x)}{f'(x_0)} x=x0f(x0)f(x),设迭代到 ∣ x − x 0 ∣ ≤ 1 ∗ 1 0 − 5 |x-x_0 |≤1*10^{-5} xx01105时结束。

2.问题分析

牛顿迭代法是取 x 0 x_0 x0之后,在这个基础上找到比 x 0 x_0 x0更接近的方程根,一步一步迭代,从而找到更接近方程根的近似根。

r r r f ( x ) = 0 f(x)=0 f(x)=0的根,选取 x 0 x0 x0作为r的初始近似值,过点 ( x 0 , f ( x 0 ) ) (x_0,f(x_0)) (x0,f(x0))做曲线 y = f ( x ) y=f(x) y=f(x)的切线L,L的方程为 y = f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) y=f(x_0)+f'(x_0)(x-x_0) y=f(x0)+f(x0)(xx0),求出L与x轴交点的横坐标 x 1 = x 0 − f ( x 0 ) f ′ ( x 0 ) x_1=x_0-\frac{f(x_0)}{f'(x0)} x1=x0f(x0)f(x0),称 x 1 x_1 x1 r r r的一次近似值;

过点 ( x 1 , f ( x 2 ) ) (x1,f(x_2)) (x1,f(x2))做曲线 y = f ( x ) y=f(x) y=f(x)的切线,并求出该切线与x轴交点的横坐标 x 2 = x 1 − f ( x 1 ) f ′ ( x 1 ) x_2=x_1-\frac{f(x1)}{f'(x1)} x2=x1f(x1)f(x1),称 x 2 x_2 x2 r r r的二次近似值;重复以上过程,得到 r r r的近似值 x n x_n xn。上述过程即为牛顿迭代法的求解过程。

3.算法设计

程序流程分析:

1)在1附近找任一实数作为 x 0 x_0 x0的初值,我们取1.5,即 x 0 x_0 x0=1.5。

2)用初值 x 0 x_0 x0代入方程中计算此时的 f ( x 0 ) f(x0) f(x0) f ′ ( x 0 ) f'(x0) f(x0);程序中用变量f描述方程的值,用fd描述方程求导之后的值。

3)计算增量h=f/fd。

4)计算下一个 x x x x x x= x 0 x_0 x0-h。

5)用新产生的 x x x替换原来的 x 0 x_0 x0,为下一次迭代做好准备。

6)若 ∣ x − x 0 ∣ > = 1 e − 5 |x-x0|>=1e-5 xx0∣=1e5,则转到步骤(3)继续执行,否则转到步骤(7)。

7)所求 x x x就是方程 a x 3 + b x 2 + c x + d = 0 ax^3+bx^2+cx+d=0 ax3+bx2+cx+d=0的根,将其输出。

4.确定程序框架

程序流程图如图所示。

在这里插入图片描述

5.迭代法求方程根

编写程序时要注意的一点是判定|x-x0|>=1e-5,许多初学者认为判定条件应该是|x-x0|<1e-5,从牛顿迭代法的原理可以看出,迭代的实质就是越来越接近方程根的精确值,最初给x0所赋初值与根的精确值是相差很多了,正是因为这个我们才需要不断地进行迭代,也就是程序中循环体的功能。在经过一番迭代之后所求得的值之间的差别也越来越小,直到求得的某两个值的差的绝对值在某个范围之内时便可结束迭代。若我们把判定条件改为|x-x0|<1e-5,则第一次的判断结果必为假,这样我们就不能进入循环体再次执行。希望初学者对于本类题目条件的判定要多加注意。

6.完整的程序

根据上面的分析,编写程序如下:

%%time
# 牛顿迭代法求方程根
# 函数功能是用牛顿迭代法求方程的根
def solution(a, b, c, d):
    x = 1.5
    x0 = x                                                          # 用所求得的x值代替x0原来的值
    # f用来描述方程的值,fd用来描述方程求导之后的值
    f = a * x0 * x0 * x0 + b * x0 * x0 + c * x0 + d
    fd = 3 * a * x0 * x0 + 2 * b * x0 + c
    h = f / fd
    x = x0 - h                                              # 求得更接近方程根的x值
    while abs(x - x0) >= 1e-5:
        x0 = x
        f = a * x0 * x0 * x0 + b * x0 * x0 + c * x0 + d
        fd = 3 * a * x0 * x0 + 2 * b * x0 + c
        h = f / fd
        x = x0 - h                                          # 求得更接近方程根的x值

    return x

if __name__ == '__main__':
    print("请输入方程的系数:")
    # a,b,c,d代表所求方程的系数
    a, b, c, d = map(float, input().split())
    print("方程的参数为:" , a, b, c, d)
    # x用来记录求得的方程根
    x = solution(a, b, c, d)
    print("所求方程的根为x=%.6f"% x)
请输入方程的系数:
方程的参数为: 2.0 -4.0 3.0 -6.0
所求方程的根为x=2.000000
CPU times: user 214 ms, sys: 78.1 ms, total: 293 ms
Wall time: 27.3 s
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飘逸高铁侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值