什麼是二分法?
二分法是求解連續函數 \(f(x)\) 之根(也就是讓 \(f(x) = 0\) 的 \(x\) 值)最古老、也最穩定可靠的方法之一。它的做法是:先找出一個函數會變號的區間 \([a, b]\),接著不斷把區間對半切開,並保留仍然包圍著根的那一半。由於每一步都保有變號的特性,只要 \(f\) 為連續函數,且 \(f(a)\) 與 \(f(b)\) 異號,二分法保證會收斂。本計算機適用於任何無因次的實函數,三角函數一律以弧度(radian)計算。
如何使用本計算機
請在 f(x) 欄位中輸入函數,並以 \(x\) 作為變數(例如 x-cos(x)、x^2-2 或 exp(x)-3)。設定下端點 a 與上端點 b,使根落在兩者之間——也就是乘積 \(f(a)\cdot f(b)\) 必須小於或等於零。再選擇最大迭代次數 n,以及要顯示的位數。工具會回傳近似的根、該點的函數值(應接近零),以及實際所需的迭代次數。
計算公式
每一步的估計值都是區間中點 \(x_n = (a_n + b_n) / 2\)。 $$ c = \frac{a + b}{2} \\[1.5em] \text{where}\quad \left\{ \begin{aligned} &\text{if } f(a)\cdot f(c) < 0 \Rightarrow b \leftarrow c \\ &\text{else} \Rightarrow a \leftarrow c \\ &\text{repeat up to } n \text{ times} \end{aligned} \right. $$ 若 \(|f(x_n)|\) 小於容許誤差,便接受 \(x_n\) 為解;否則演算法會保留仍然變號的那一半:若 \(f(a_n)\cdot f(x_n) > 0\),表示根在右側(令 \(a = x_n\)),否則在左側(令 \(b = x_n\))。包圍區間的寬度會以 \((b-a)/2^n\) 的速度縮小,因此收斂為線性——大約每一步多正確一個二進位位數。
範例演算
以 \(f(x) = x - \cos(x)\) 在區間 \([-10, 10]\) 為例:\(f(-10) \approx -10.84\)(負值),\(f(10) \approx 10.84\)(正值),所以根已被成功包圍。不斷對分後,會收斂到 \(x \approx 0.7390851332151607\),也就是著名的「Dottie 數」(滿足 \(x = \cos x\) 的唯一實數解),此時 \(f(x)\) 實質上等於零。
如何手工進行二分法
二分法透過重複平分一個已知包含根的區間來尋找 \(f(x)=0\) 的根。它依賴於中值定理:如果 \(f\) 在 \([a,b]\) 上連續,且 \(f(a)\) 和 \(f(b)\) 有相反的符號,則根必定位於它們之間。
- 驗證括號。確認 \(f(a)\cdot f(b)<0\)。如果乘積為正,則不能保證區間包含根 — 選擇不同的 \([a,b]\)。
- 計算中點。\(m=\dfrac{a+b}{2}\)。
- 計算函數值。求 \(f(m)\)。如果 \(f(m)=0\)(或在容差範圍內),\(m\) 就是根,您停止。
- 根據符號替換端點。如果 \(f(a)\cdot f(m)<0\),根在 \([a,m]\) 中,設 \(b\leftarrow m\)。否則根在 \([m,b]\) 中,設 \(a\leftarrow m\)。
- 重複步驟 2–4,直到 \(|b-a|<\text{tol}\) 或 \(|f(m)|<\text{tol}\),或直到達到最大迭代次數。
範例:\(f(x)=x^{3}-x-2\) 在 \([1,2]\) 上。檢查:\(f(1)=-2\),\(f(2)=4\),乘積 \(<0\) — 括號有效。
| 迭代 | a | b | m=(a+b)/2 | f(m) | 新區間 |
|---|---|---|---|---|---|
| 1 | 1.0000 | 2.0000 | 1.5000 | −0.125 | [1.5, 2] |
| 2 | 1.5000 | 2.0000 | 1.7500 | 1.6094 | [1.5, 1.75] |
| 3 | 1.5000 | 1.7500 | 1.6250 | 0.6660 | [1.5, 1.625] |
| 4 | 1.5000 | 1.6250 | 1.5625 | 0.2522 | [1.5, 1.5625] |
| 5 | 1.5000 | 1.5625 | 1.5313 | 0.0591 | [1.5, 1.5313] |
| 6 | 1.5000 | 1.5313 | 1.5156 | −0.0340 | [1.5156, 1.5313] |
經過更多迭代後,區間收斂到真實根 1.521380,這也是三次方程 \(x^{3}-x-2=0\) 的唯一實根,可以用1.521380直接求解器找到。
迭代次數與容差和括號寬度的關係
每個二分步驟將區間減半,因此經過 \(n\) 次迭代後括號寬度為 \((b-a)/2^{\,n}\)。要達到根位置的容差 \(\text{tol}\),您需要大約
$$n \approx \log_2\!\left(\frac{b-a}{\text{tol}}\right).$$計數只隨著精度的對數增長,因此即使非常嚴格的容差也只需相對較少的步驟。下表顯示了幾種組合的四捨五入迭代次數。
| 初始寬度 \(b-a\) | 目標容差 | \(\log_2((b-a)/\text{tol})\) | 所需迭代次數 |
|---|---|---|---|
| 1 | \(10^{-3}\) | 9.97 | 10 |
| 1 | \(10^{-6}\) | 19.93 | 20 |
| 1 | \(10^{-10}\) | 33.22 | 34 |
| 10 | \(10^{-6}\) | 23.25 | 24 |
| 20 | \(10^{-6}\) | 24.25 | 25 |
| 100 | \(10^{-8}\) | 33.22 | 34 |
| 0.5 | \(10^{-12}\) | 38.86 | 39 |
例如,寬度為 20 的括號精煉至 \(10^{-6}\) 需要 \(\lceil\log_2(20/10^{-6})\rceil=\lceil 24.25\rceil=\) 25 次迭代,寬度為 1 的括號精煉至 \(10^{-10}\) 需要 \(\lceil 33.22\rceil=\) 34 次。將起始寬度減半恰好節省一次迭代;將精度平方(多一位十進制小數位)約耗費 3.3 次迭代。
關鍵術語
- 根。函數為零的值 \(x^{*}\),即 \(f(x^{*})=0\);也稱為零點或方程的解。
- 括號 / 區間 \([a,b]\)。被認為包含根的一對端點。對於二分法,它必須滿足符號改變條件。
- 符號改變。條件 \(f(a)\cdot f(b)<0\),意味著 \(f\) 在端點處有相反的符號。對於連續的 \(f\),這保證了至少有一個根在其間(中值定理)。
- 中點。當前區間的中心,\(m=(a+b)/2\);每一步測試該點並舍棄不可能包含根的一半。
- 容差。停止迭代的精度目標,應用於區間寬度 \(|b-a|\) 或殘差 \(|f(m)|\)。
- 收斂(線性)。二分法進行線性收斂:每步誤差大約減半(誤差 \(\le (b-a)/2^{n}\)),給出穩定但不加速的進展 — 每次迭代約多一位正確的二進制數字。
- 迭代。計算中點、計算函數值和更新端點的一個完整週期。迭代次數由最大迭代次數設定限制。
常見問題
為什麼會出現「無變號」的錯誤訊息?二分法需要 \(f(a)\) 與 \(f(b)\) 異號。請調整 \(a\) 與 \(b\),直到它們分別位於根的兩側。
它能一次找出多個根嗎?不行——它只會回傳包圍區間內的單一個根,而且無法偵測曲線僅與橫軸相切、卻沒有穿越的情況。
為什麼它比牛頓法(Newton's method)慢?二分法為線性收斂,每一步大約多正確一個二進位位數;而牛頓法為二次收斂。實務上常先用二分法取得一個安全的起始點,再交由收斂更快的方法進一步精算。