跳转至

怎样把有根证明变成误差可证的算法?

先备知识

零点定理、闭区间与 Python 函数调用。算法源码唯一位于 src/mathbook_examples/bisection.py

学习目标

从连续异号条件导出二分不变量、误差界和停止准则,并解释实现拒绝的输入。

牵引问题

怎样返回一个数,并证明它离区间中的某个真根不超过给定容差?

探索与猜想

保留异号半区间就保留至少一个根;区间长度每步减半,中点到区间内任意根至多为半长。

概念与理论

算法:认证二分法

输入连续 \(f\)、有限端点 \(a<b\)\(f(a)f(b)\le0\)、容差 \(\tau>0\)。若端点是根立即返回;否则反复取安全中点 [ m=a+\frac{b-a}{2}, ] 若命中根则返回,否则保留仍异号的一半,直到区间半长不超过 \(\tau\)

循环不变量是: [ a_n<b_n,\quad f(a_n)f(b_n)\le0,\quad [a_n,b_n]\text{ 至少含一个根}. ]

定理:二分误差证书

完成 \(n\) 次二分后,区间长度为 \((b-a)/2^n\)。若返回其中点 \(r_n\),则对 该区间中的某个根 \(c\), [ |r_n-c|\le\frac{b-a}{2^{n+1}}. ] 要使误差不超过 \(\tau\),选择满足 [ 2^{n+1}\ge\frac{b-a}{\tau} ] 的步数。证明只用根仍在区间内以及中点到区间内任一点不超过半长。\(\square\)

小残差 \(|f(r)|\) 不是无条件的根误差界;函数可能非常平坦。

例题与迁移

例题1:调用唯一实现

from mathbook_examples.bisection import bisect
result = bisect(lambda x: x**3 + x - 1, 0.0, 1.0, tolerance=1e-6)
print(result.root, result.error_bound)
error_bound 来自最终有根区间,不依赖已知“标准答案”。

例题2:先验步数

初始长度为1,要中点误差不超过 \(10^{-6}\),取满足 \(2^{n+1}\ge10^6\) 的最小 \(n\)。实现还需给足迭代预算。

即时检验与回望

检验1:为什么保留异号?

答案

它使零点定理每一步都可再次应用,保证根不被丢弃。

检验2:端点为根怎么办?

答案

立即返回该端点,误差界为零,不必二分。

习题与答案

习题1

初始长度1,20次二分后中点误差界是多少?

答案

\(2^{-21}\)

习题2

二分法保证根唯一吗?

答案

不保证,只保证最终区间至少含一个根。

习题3

端点同号能否直接运行?

答案

不能;缺少零点存在证书,即使区间内部偶然有偶数个根也无法由此合同确认。

习题4

为何容差必须为正且有限?

答案

非正容差不能形成可达停止条件,非有限值不能表达有效误差目标。

习题5

为什么拒绝函数返回 NaN

答案

NaN 无法比较符号,会破坏异号不变量与分支判断。

常见误区与后续

二分误差是区间证书,不是残差猜测;算法需要连续性、异号、有限输入、正容差和足够 预算。下一单元统一比较三类证书。