我寫了一個 對 二元隱函數 數值求解 的 程序 。
項目地址 : https://github.com/kelin-xycs/StepApproach
進入 項目頁面 后 點擊 右邊綠色 的 “Clone or download” 按鈕 就可以下載 項目文件 了 。 項目中 只有一個 程序文件 StepApproach.html , 用 Html5 + javascript 寫的, 用 瀏覽器 打開 就可以運行 。
二元隱函數 就是一個 二元方程, 就是 一個方程 有 2 個 未知數, 把 未知數 看作 變量, 那 二元方程 就是 二元隱函數 。
一個未知數 看作 自變量, 另一個 未知數 看作 因變量 。
我們把 自變量 統稱為 x, 因變量 統稱為 y 。
這樣, 二元隱函數 可以 表示成 : y = f ( x, y ) , 或者 x = f ( x, y ) , 或者 f ( x, y ) = C , C 為 常量 。
比如, 我們可以看看 一個 極坐標系 的 二元隱函數 : ρ = tan ( θ + ρ ) , θ 為 自變量, ρ 為 因變量 。
也可以寫成 : y = tan ( x + y ) 。
對 二元隱函數 求解 就是 求 當 x = 某值 時, y 的 值 是多少 。
我寫的 程序 默認就是 對 y = tan ( x + y ) 這個 二元隱函數 求解 的 , 效果如下 :
x 表示 當 x = 某值 時 的 x, 就是 求 這個 x 對應 的 y 。
y 初始值 表示 數值求解 用於 匹配 的 y 的 初始值 , 記為 y₀ 。
數值求解 的 算法 是這樣, 從 y₀ 開始, 用 y₀ 加上 一定 的 步長, 得到一個 y 值, 記為 y1, 把 y1 和 x 代入 方程, 計算得出 方程 等式兩邊 的 值, 然后求 等式兩邊 的 值 的 差 的 絕對值, 記為 diff 。 如果 diff 很小, 說明 等式兩邊 相差小, 則 y1 比較符合 x 對應 的 y, 即 y1 比較接近 理論解 。
如果 diff 很大, 說明 等式兩邊 相差大, 則 y1 不太符合 x 對應 的 y, 即 y1 比較遠離 理論解 。
所以, diff 也表示計算精度 。 diff 越小,計算精度越高, diff 越大,計算精度越低 。
上述過程 稱為 一個步長 的 匹配, 在完成一個步長的 匹配 后, 計算機 會 增加一個 步長, 即 讓 y₀ 加上 2 個步長, 即 :
y2 = y₀ + 步長 * 2
把 y2 和 x 代入方程, 求 diff, 這和 y1 的 過程 一樣 , 同理, 求
y3 = y₀ + 步長 * 3
y4 = y₀ + 步長 * 4
y5 = y₀ + 步長 * 5
……
的 diff, diff 最小 的 yn 就是 最終輸出 的 解 。
而 求多少個 yn 呢? 這由 步數 決定, 比如 可以設定 步數 為 10, 或者 100 等等 。
這樣 求出來 的 解 還是 很粗略 的, 為了 提高 解 的 精度, 可以 設定 一個 新的 步長 和 步數, 再進行一輪 匹配 。
新一輪 的 步長 應該 比 上一輪 小, 表示 更 精細 的 匹配 。
用 上一輪 的 解(上一輪 中 diff 最小的 yn) 作為 下一輪 的 初始值 y₀ 。
這樣 經過 若干輪 匹配 之后, 得到 的 解 就 比較 精確 了 , 或者說 diff 很小 。
這個算法 稱為 跨越逼近法, 又稱為 離散統計逼近法 。
這個算法 的 時間復雜度 是 O ( 第 1 輪 步數 + 第 2 輪 步數 + …… + 第 n 輪 步數 ) 。
如果 進行 9 輪 匹配, 每輪 步數 是 10, 則 時間復雜度 是 O ( 9 * 10 ) = O ( 90 ) 。
上面的 匹配過程 是 y₀ + 步長 * n, 實際上, 還有 y₀ - 步長 * n , 也就是 負方向匹配 , 匹配 是 雙向 的, y₀ + 步長 * n 是 正方向匹配 。
所以, 在 時間復雜度 中, O ( 1 ) 包含了 2 次匹配, 一次 是 正向匹配, 一次 負向匹配 。
但是, 為了 體現 步長 * 步數 的 關系, 在 計算 時間復雜度 時 沒有區分 正向負向匹配, 把 正負向 2 次 匹配 算作 一次 操作 O ( 1 ) 。