整数乘法的长征

Published on

清晰版

约定

现在要计算两个 $n$ 位二进制数 $a$ 和 $b$ 的乘积,这是为了方便描述,一下算法可以直接应用到任意进制的情况。

我们的计算机每次仅可以对一位二进制位进行操作,我们的复杂度也是在这样的机器上进行计算的。

Karatsuba 型算法时期

Karatsuba 算法

前置知识

Karatsuba 提出了第一个能在低于 $\mathcal O\left(n^2\right)$ 的时间内计算整数乘法的算法去,其复杂度为 $\Theta \left(n^{\log_23}\right)$。

不妨设 $n$ 是偶数,把 $a$ 表示为 $a_0 + a_1 \cdot 2^{n / 2},$b$ 为 $b_0 + b_1 \cdot 2^{n / 2}$。

$$ab = a_0b_0 + \left(a_0b_1 + a_1b_0\right) \cdot 2^{n / 2} + a_1b_1 \cdot 2^n$$

而其中 $a_0b_1 + a_1b_0 = \left(a_0 + a_1\right)\left(b_0 + b_1\right) - a_0b_0 - a_1b_1$

于是我们只需要计算 $a_0b_0, \left(a_0 + a_1\right)\left(b_0 + b_1\right), a_1b_1$ 三个乘法即可。

复杂度:$T\left(n\right) = 3T\left(n / 2\right) + \Theta\left(n\right) = n^{\log_23}$。

Toom-Cook 算法

前置知识

观察 Karatsuba 算法 的本质:计算二次多项式 $\left(a_0 + a_1x\right)\left(b_0 + b_1x\right)$ 在 $0, 1, \infty$ 这 $3$ 处的点值,然后还原。

根据这个思路,我们可以把 $m$ 写成 $m_0 + m_1x + m_2 x + \ldots + m_kx^k$,那么 $ab$ 就是一个 $2k$ 次多项式,我们需要求出 $2k + 1$ 个点值。

$$T\left(n\right) = \left(2k + 1\right) T\left(n / \left(k + 1\right)\right) + k^{\mathcal O\left(1\right)}n$$

其中 $k^{\mathcal O\left(1\right)}$ 为拉格朗日插值时需要付出的代价。

$$T\left(n\right) = \mathcal O\left(n^{\log_{k + 1}2k + 1}k^{\mathcal O\left(1\right)}\right) = \mathcal O\left(n \cdot \exp\left\{\mathcal O\left(\frac{\log n}{\log k}\right) + \mathcal O\left(\log k\right)\right\}\right)$$

取 $\log k = \Theta\left(\sqrt{\log n}\right)$,可以做到 $\mathcal O\left(2^{\sqrt{\log^3 n}}\right)$。

快速傅里叶(Fourier)变换时期

Cooley-Tukey 算法

施工中。。。

参考

https://www.cnblogs.com/Elegia/p/18020040/integer-multiplication


No comments

Post a comment