使用SICP不动点法求解a²+a³=392时出现OverflowError问题排查
解决不动点迭代的OverflowError问题
首先,咱们来搞清楚为什么会出现这个溢出错误:
你把原方程 a² + a³ = 392 变形为 x = 392/(x + x²) 来做不动点迭代,但这个迭代函数的核心问题是迭代过程完全发散,根本不会收敛到正确的根。咱们走一遍初始几次迭代就一目了然:
- 初始猜测是1,第一次计算得到
392/(1+1) = 196 - 第二次用196计算:
392/(196 + 196²) ≈ 0.01015 - 第三次用0.01015计算:
392/(0.01015 + 0.01015²) ≈ 38244 - 第四次又会得到一个极小的数,就这样在极大值和极小值之间来回跳,数值越来越极端,最后超出Python浮点数的范围,自然触发了OverflowError。
两种可行的修正方案
方案1:重新变形方程,让迭代收敛
原方程可以改写成 x³ = 392 - x²,也就是 x = (392 - x²)^(1/3),这个迭代函数是收敛的。修改后的代码如下:
import math tolerance = 0.00001 def fixed_point(f, guess): while True: nex = f(guess) if abs(guess - nex) < tolerance: return nex else: guess = nex def f(x): return (392 - x**2)**(1/3) print(fixed_point(f, 1)) # 输出约7.0,正好是正确的根!
方案2:用平均阻尼抑制震荡(SICP里的经典技巧)
如果你还是想用原来的变形方式,可以加入平均阻尼——每次迭代取当前猜测值和下一个计算值的平均值,这样就能避免剧烈震荡,让迭代收敛。代码修改如下:
import math tolerance = 0.00001 def fixed_point(f, guess): while True: nex = f(guess) if abs(guess - nex) < tolerance: return nex else: guess = nex # 给原迭代函数加上平均阻尼 def f(x): return (x + 392/(x + x**2)) / 2 print(fixed_point(f, 1)) # 同样会收敛到7.0
验证结果
最后咱们验证一下,7确实是原方程的根:7² + 7³ = 49 + 343 = 392,完全符合要求。
内容的提问来源于stack exchange,提问作者Wizard
相关产品推荐
相关产品推荐

