牛頓迭代法 - 求解非線性方程根的近似解

LilyFlower發表於2024-10-13

牛頓迭代法 - 求解非線性方程根的近似解

在演算法中,牛頓迭代法主要用於求解非線性方程或最佳化問題。它是一種迭代演算法,透過不斷逼近來找到函式的根或者最小化/最大化某個目標函式。

這裡呢,我們重點講一下如何求解線性方程 \(F(X) = 0\) 近似根的大致步驟。

  1. 選擇一個初始猜測值\(x_0\):
    • 這個初始猜測應該儘可能接近實際的根,一個好的初始猜測可以加速收斂過程,並且有助於避免演算法陷入區域性極小值或不收斂的情況。
  2. 定義迭代公式:
    • 牛頓迭代法的迭代公式是:\(X_(n+1) = X_n - \frac{F(X_n)}{F^`(X_n)}\)
    • 其中 \(F^`(X_n)\) 是函式 \(F(X)\) 在點 \(X_n\) 處的一階導數。
  3. 執行迭代過程:
    • 使用上面的迭代公式。從$ X_0$ 開始計算 \(X_1, X_2, X_3, ...\) ,直到滿足停止條件。
  4. 設定停止條件:
    • 停止條件通常有兩種形式:
      • 當連續兩次迭代的結果足夠接近時,即 \(∣X_n+1 - X_n∣ < ϵ\) ,其中 ϵ 是預設的小正數。
      • 或者當函式值足夠接近於零時,即 \(|F(X_(n+1))| < ϵ\)
    • 有時還會設定最大迭代次數以防止無限迴圈。
  5. 檢查結果的有效性:
    • 確認最終得到的 X 值確實是 \(F(X)=0\) 的根。如果函式在該點附近的行為複雜(如存在多個根或導數為零),可能需要進一步分析。

這裡以牛客的一道題來舉個例子:

計算一個浮點數的立方根而不使用庫函式

我們就可以使用牛頓迭代法來逼近結果。

對於求解X的立方根,我們需要找到滿足 \(Y^3 = X\)\(Y\) , 這裡可以透過解方程 \(F(Y) = Y^3 - X = 0\) 來實現,牛頓迭代的公式為:

\(Y_(n+1) = Y_n - \frac{F(Y_n)}{F^`(Y_n)}\)

其中 \(F(Y) = Y^3 - X\) , 導數 \(F^`(Y) = 3Y^2\)

帶入後得到:

\(Y_(n+1) = Y_n - \frac{Y^3_n - X}{3Y_n^2}\)

下面是Java程式碼的實現:

public class Main {
    public static void main(String[] args) {
        double x = 27.0;    // 求Math.sqrt(x)
        double tolerance = 1e-10;   // 允許的誤差
        System.out.printf("%f\n",calculateCubeRoot(x, tolerance));
    }

    private static double calculateCubeRoot(double x, double tolerance) {
        if (x == 0) return 0;   // 特殊值處理

        double y = x;   // 猜測初始值
        double diff;    // 計算出來的誤差

        do {
            double nextY = y - (y * y * y - x)/(3 * y*y);   // 迭代公式,計算出新的迭代值
            diff = Math.abs(nextY - y); // 計算出新的迭代值與舊的迭代值之間的誤差
            y = nextY;  // 更新迭代後的值
        } while (diff > tolerance);

        return y;   // 滿足誤差後跳出迴圈直接返回最終迭代後的結果
    }
}

執行結果如下:

3.000000

相關文章