我写了一个 对 二元隐函数 数值求解 的 程序 。
项目地址 : 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 ) 。