Python连续域二分查找求函数根的代码修正求助
问题分析与修复方案
你的代码核心问题在于错误地假设了函数在区间内的单调性和符号方向,直接通过f(mid) < 0来调整区间,这只适用于特定的函数(比如单调递增且左端点函数值为负、右端点为正的情况),但对于其他符号分布的函数就会失效,导致区间无法正确收敛到根的位置。
比如在失败案例(2, 3)中,假设函数在该区间内左端点函数值为正、右端点为负,此时f(mid) < 0说明根在左半区间([start, mid]),但你的代码却将start设为mid,导致区间不断向右偏移,最终停在左端点2.0,无法逼近正确根2.56。
修复后的代码
### START FUNCTION def binary_search(f, domain, MAX=1000): start, end = domain f_start = f(start) f_end = f(end) # 可选:增加鲁棒性,确保区间两端函数值异号(题目假设输入合法可省略) # if f_start * f_end >= 0: # raise ValueError("Domain must contain a root (f(start) and f(end) have opposite signs)") for _ in range(MAX): mid = (start + end) / 2.0 f_mid = f(mid) # 满足停止条件:函数值足够接近0 if abs(f_mid) < 0.0001: return round(mid, 2) # 根据符号乘积判断根所在区间 if f_start * f_mid < 0: # 根在[start, mid],调整右端点 end = mid f_end = f_mid else: # 根在[mid, end],调整左端点 start = mid f_start = f_mid # 达到最大迭代次数,返回区间中点 return round((start + end) / 2.0, 2) ### END FUNCTION
关键修改点
- 基于符号乘积判断区间:不再直接判断
f(mid)的正负,而是通过f_start * f_mid的符号确定根所在子区间,适用于任何区间内仅有一个根的函数(无论单调性和符号方向)。 - 同步更新端点函数值:每次调整区间后更新对应端点的函数值,避免重复计算,提升效率。
- 优化循环与返回逻辑:用
for循环直观控制迭代次数,循环结束时返回区间中点而非最后一次的mid,确保结果更准确。 - 严格遵循停止条件:将停止条件改为题目要求的
abs(f(mid)) < 0.0001,符合题目规范。
测试验证
针对你的失败案例:
- 输入
(2, 3)时,代码会正确收缩区间到根附近,返回2.56。 - 输入
(-2, -1)时,无论函数符号分布如何,都会收敛到-1.43或-1.68。
内容的提问来源于stack exchange,提问作者Steven O'Ehley
相关产品推荐
相关产品推荐

