二分法模拟器 返回
数值方法模拟器

二分法模拟器 — 区间二等分求根

以 f(x)=x³−2x−5 为例,实时可视化中点 c=(a+b)/2 把区间每次缩小一半的二分法收敛过程:函数曲线上的中点序列与区间宽度对数衰减曲线,全部参数可滑动调节。

参数
初始区间左端 a1.00
初始区间右端 b3.00
最大迭代次数30
容差 1e^−n6
计算结果
收敛的根
迭代次数
最终区间宽度
收敛状态
函数曲线与区间 [a, b](f(x)=x³−2x−5)
区间宽度 (b−a) 的收敛曲线(log10)
理论与主要公式

$$c_n = \frac{a_n + b_n}{2}, \quad [a_{n+1}, b_{n+1}] = \begin{cases} [a_n, c_n] & f(a_n)\,f(c_n) < 0 \\ [c_n, b_n] & \text{otherwise} \end{cases}$$

二分法的更新规则:根据中点 c_n 处的符号选择仍包含根的半区间。

$$f(x) = x^{3} - 2x - 5, \quad f(a_0)\cdot f(b_0) < 0$$

测试函数(牛顿当年的原例题)与前提条件。实根 x ≈ 2.094551482。

$$|b_n - a_n| < \varepsilon, \qquad N \approx \log_2\!\left(\frac{b_0 - a_0}{\varepsilon}\right)$$

收敛判据与所需迭代次数。容差 ε=1e^−n 时 N ≈ log₂((b₀−a₀)/ε)。线性收敛(每次迭代误差减半)。

什么是二分法

对连续函数 f(x),若 f(a)·f(b)<0(两端异号),就把区间在中点处切成两半,保留仍含符号变化的那一半。它是最古典也最稳健的根求解方法——唯一保证"绝不发散"的迭代算法。

🙋
这跟牛顿法有什么区别?听说牛顿法快得多。
🎓
仅看速度的话牛顿法确实快——它是"二阶收敛",误差每次迭代差不多平方一次。二分法只是"线性收敛",每次把区间砍一半。从单位区间到 1e−6 大约要 log₂(2/1e−6)≈21 次。但二分法有个绝对优势:永远不会发散。只要 f(a)·f(b)<0 成立,由中间值定理可知 (a,b) 内必有根,二分法一步步逼近就是了。生产代码常用"混合策略":先用二分法定位根的大致位置,再切换到牛顿法或 Brent 法快速精化。
🙋
如果左右端点函数值都是正的(或都是负的)呢?
🎓
那二分法的前提就破了。试试在模拟器里设 a=1, b=2:f(1)=−6, f(2)=−1,都是负数,会显示"同号错误"。中间值定理只在函数变号时才保证区间内有根;若不变号,区间内可能有零个或偶数个根,二分法都抓不到。补救办法:调整 a 或 b 让 f 的符号改变;或先粗略画一遍 f(x) 找出根的存在区间。任何严肃的二分法实现都会在进入迭代前先检查 f(a)·f(b)<0。
🙋
如果把容差收紧到 1e−12,迭代次数是不是要翻倍?
🎓
差不多翻倍。线性收敛的代价是:把容差从 1e−6 收紧到 1e−12 要再加 log₂(10⁶)≈20 次。牛顿法只多 1~2 次,差距很大。二分法的下限是双精度浮点机器精度(约 2.2e−16),再往下加 (a+b)/2 的舍入误差反而会出问题。实务里一般用二分法到 1e−6 左右,更严的精度交给牛顿法或割线法处理。

物理模型与主要数式

二分法是把连续函数的中间值定理(IVT)直接翻译成算法:若 f(a)·f(b)<0,则 (a, b) 内至少有一个根。

$$c_n = \frac{a_n + b_n}{2}$$

计算中点后,按符号选择仍含变号的那半区间:

$$[a_{n+1}, b_{n+1}] = \begin{cases} [a_n, c_n] & f(a_n)\,f(c_n) < 0 \\ [c_n, b_n] & f(a_n)\,f(c_n) > 0 \end{cases}$$

误差上界(线性收敛):

$$|c_n - x^{*}| \le \frac{b_0 - a_0}{2^{n+1}}$$

达到容差 ε 所需的迭代次数:

$$N \ge \log_{2}\!\left(\frac{b_0 - a_0}{\varepsilon}\right)$$

每次迭代有效位数约增 log₁₀(2)≈0.301 位——比牛顿法的"位数翻倍"慢得多,但绝对可靠。

实际应用

非线性求解器的安全网(CAE):Abaqus、ANSYS 的非线性结构分析在牛顿迭代发散时,会回退到二分式的区间收缩。Riks 弧长法在内层迭代失败时也会用二分搜索调整弧长参数。

状态方程的反求(CFD、热流体):真实气体或液体的状态方程通常只能由 (ρ, T) 显式得到 p,但反过来从 (p, T) 求 ρ 几乎都没有闭式解。SUPG/PISO/SIMPLE 的压力-速度耦合子步内部,通常用二分法或 Brent 法反求。

显式动力学的接触时刻定位:显式 FEM 中一个节点在某时间步内穿入接触面时,需要用二分法找出穿透量恰好为零的精确接触时刻 t*,再以此为新的步长重做该步。

优化的线搜索:梯度下降、共轭梯度、牛顿型优化在每步要确定步长 α 满足 Wolfe 条件,常用二分法(或黄金分割、Armijo 后退)确定满足条件的 α 区间。

常见误解与注意事项

第一个常见误解是 "二分法线性收敛太慢,没什么用"。但要注意:二分法每步只调用一次 f(x);牛顿法每步还要计算 f' 或整个雅可比矩阵,在 CAE 这种高维问题里组装切线刚度的代价远超函数计算。按单步代价算,二分法常常是最便宜的选择。

第二,"中间值定理保证唯一根" 是错的。它只保证区间内 奇数个 根。可能有 3 个、5 个;二分法只会收敛到其中一个,但具体收敛到哪一个,取决于中点序列的走向。在模拟器里把 a=−2, b=3 这种大区间扫一遍,再逐步缩窄,就能看到不同情况下收敛到不同根的现象。

第三,不连续陷阱。中间值定理要求函数连续。像 1/x 这种函数在 x=0 处变号但并没有零点,二分法会乐呵呵地"收敛"到这个不连续点。所以要么在使用前确认函数连续,要么先可视化一下函数。

常见问题

常用三种:(1) 区间宽度 |b−a| < ε(位置精度);(2) 残差 |f(c)| < ε;(3) 最大迭代次数。生产代码通常用 (1) 与 (3) 配合,本模拟器也是任一触发即停。仅用残差判据有早停风险——根附近 f'(x*) 很小的话,残差可能很早变小但实际离根还远。
割线法(Secant method)用 (a, f(a)) 与 (b, f(b)) 连成的直线与 x 轴的交点作下一估计,超线性收敛(阶 φ≈1.618),比二分法快,但不保持区间包围、可能发散。Brent 法把二分、割线、逆二次插值结合并自动切换,是 SciPy brentq、MATLAB fzero 的标准实现,兼顾稳健与速度。对纯稳健需求,二分法仍是黄金标准。
纯二分法仅适用一维。高维类比物有"区间分析"、"Krawczyk 算子"、"区间剖分算法",但实现复杂得多。CAE 实务中多维非线性求解几乎都用牛顿-拉夫森法(带雅可比)或拟牛顿变种;二分法只出现在内层一维子问题中。
先做粗网格搜索——在搜索范围内取 10~100 个点采样 f(x),相邻样本符号变化处即为候选区间;然后用二分法精细定位。物理约束(温度高于绝对零度、压力为正等)也常自然提供边界。对本工具中的 3 次函数,取 [−5, 10] 这种足够宽的区间一定包含实根。