数值计算
Karatsuba 乘法
假定 是 位数,不妨假定 是偶数,那么 可以拆成两个部分。 那么 其中 因此可以省去一次乘法。
Karatsuba 乘法利用上述等式来减少乘法次数。整个算法采用递归实现。
如果 n == 1,那么直接计算 x * y 并返回。
否则,按照前面的描述,将 x 拆成 a b 两部分,将 y 拆成 c d 两部分。分别计算 ac = a * c 和 bd = b * d。为方便表示中间项,引入变量 p = a + b 和 q = c + d,则 adbc = p * q - ac - bd。最终结果为 pow(10, n) * ac + pow(10, n / 2) * adbc + bd。
具体实现可以参考 BigInteger.cc。
Strassen 矩阵乘法
假定 是两个 的矩阵,乘积为 ,其第 行第 列的元素为
最朴素的算法是依次遍历 ,使用三层 for 循环,时间复杂度为 。
下面考虑分治法。为便于划分,假定 为偶数;若不是,可以在矩阵周围补零。将 分别拆成四个 的子矩阵: 那么 需要递归调用八次矩阵乘法,算法的时间复杂度仍为 。
如果能够将每层递归中的矩阵乘法次数从八次减少到七次,时间复杂度便可降至 。这就是 Strassen 矩阵乘法的巧妙之处。首先执行七次递归调用: 那么 下面验证各个分块的计算结果: