随机算法
1 Las Vegas 型随机算法
1.1 特点
- 通过修改确定性算法得到,一般将算法的某步的确定型选择变成随机选择
- 一次运行可能得不到解;若得到解,则解 一定是正确的
- 改进途径:与确定型算法相结合
- 有可能改进确定型算法平均情况下的时间复杂度
有效的 Las Vegas 算法:期望运行时间是输入规模的多项式且总能给出正确答案的随机算法。
1.2 随机快速排序
算法:随机快速排序
输入:包含 \(n\) 个元素的数组
输出:经过排序的 \(n\) 个元素的数组
\[
\begin{aligned}
& \textbf{算法: } \text{RandomizedQuickSort} \\
& \textbf{输入: } A[1..n] \\
& \textbf{输出: } \text{排序后的数组} \\
& 1. \quad \textbf{if } n \leq 1 \textbf{ then return } A \\
& 2. \quad \text{从数组中随机选择一个元素作为枢轴元素 } p \\
& 3. \quad \text{把数组元素分为三个子数组,按 } A, B, C \text{ 顺序排列} \\
& 4. \quad \quad A: \text{包含比枢轴元素小的元素} \\
& 5. \quad \quad B: \text{包含与枢轴元素相等的元素} \\
& 6. \quad \quad C: \text{包含比枢轴元素大的元素} \\
& 7. \quad \text{对 } A \text{ 和 } C \text{ 递归地执行上述步骤} \\
& 8. \quad \textbf{return } A \circ B \circ C
\end{aligned}
\]
定理
设数组含 \(n\) 个不同元素,随机快速排序算法的期望比较次数:
\[
T(n) \leq 2n \ln n
\]
证明
随机选取枢轴元素,其位于排序后第 \(i\) 位置(\(i = 0, 1, \ldots, n-1\))的概率是 \(1/n\)。\(A\) 和 \(C\) 的元素数分别是 \(i\) 个和 \(n-i-1\) 个,得:
\[
T(n) = (n-1) + \frac{1}{n} \sum_{i=0}^{n-1} (T(i) + T(n-i-1)) = (n-1) + \frac{2}{n} \sum_{i=1}^{n-1} T(i)
\]
解为 \(\Theta(n \log n)\)。可归纳证明精确上界是 \(T(n) \leq 2n \ln n\):
\[
T(n) \leq (n-1) + \frac{2}{n} \sum_{i=1}^{n-1} 2i \ln i \leq (n-1) + \frac{2}{n} \int_1^n 2x \ln x \, dx
\]
其中 \(\int 2x \ln x \, dx = x^2 \ln x - \frac{x^2}{2} + C\),代入得:
\[
T(n) \leq (n-1) + \frac{2}{n} \left( n^2 \ln n - \frac{n^2}{2} + \frac{1}{2} \right) \leq 2n \ln n
\]
\[\square\]
1.3 随机选择算法
算法:RandSelect
从 \(A[p..r]\) 中选第 \(k\) 小。
\[
\begin{aligned}
& \textbf{算法: } \text{RandSelect}(A, p, r, k) \\
& \textbf{输入: } A, p, r, k \\
& \textbf{输出: } A[p..r] \text{ 中第 } k \text{ 小的元素} \\
& 1. \quad \textbf{if } p = r \textbf{ then return } A[p] \\
& 2. \quad i \leftarrow \text{Random}(p, r) \\
& 3. \quad \text{以 } A[i] \text{ 为标准划分 } A \\
& 4. \quad j \leftarrow \text{划分后小于等于 } A[i] \text{ 的数构成数组的大小} \\
& 5. \quad \textbf{if } k \leq j \textbf{ then} \\
& 6. \quad \quad \textbf{return } \text{RandSelect}(A, p, p+j-1, k) \\
& 7. \quad \textbf{else} \\
& 8. \quad \quad \textbf{return } \text{RandSelect}(A, p+j, r, k-j)
\end{aligned}
\]
时间期望值估计:
假设 \(1..n\) 中每个数被选的概率相等,并且保守地假设第 \(k\) 小元素总是出现在划分后两个数组中较大的数组,则:
\[
T(n) \leq \frac{2}{n}\sum_{i=\lceil n/2\rceil}^{n-1} T(i) + O(n)
\]
设划分一次的线性时间不超过 \(tn\)。归纳证明 \(T(n) \leq cn\):假设对所有 \(k<n\) 成立,则
\[
\begin{aligned}
T(n)
&\leq \frac{2}{n}\left(c\left\lceil\frac{n}{2}\right\rceil+c\left(\left\lceil\frac{n}{2}\right\rceil+1\right)+\cdots+c(n-1)\right)+tn \\
&\leq \frac{2c}{n}\cdot \frac{\left(\frac{n}{2}+n-1\right)\frac{n}{2}}{2}+tn \\
&= \frac{3cn}{4}-\frac{c}{2}+tn \\
&\leq cn
\end{aligned}
\]
取 \(c \geq 4t\) 即可。因此随机选择算法的期望运行时间为 \(O(n)\)。
1.4 随机 n 后放置
算法:BoolQueen
\[
\begin{aligned}
& \textbf{算法: } \text{BoolQueen}(n) \\
& 1. \quad k \leftarrow 1 \quad \text{// } k \text{ 放皇后的行号} \\
& 2. \quad \text{count} \leftarrow 0 \quad \text{// count 放好的皇后数} \\
& 3. \quad \textbf{while } k \leq n \textbf{ do} \\
& 4. \quad \quad S \leftarrow \emptyset \\
& 5. \quad \quad \textbf{for } i \leftarrow 1 \textbf{ to } n \textbf{ do} \quad \text{// } i \text{ 为待选列号} \\
& 6. \quad \quad \quad \text{检查 } i \text{ 与前面 } k-1 \text{ 个皇后的相容性} \\
& 7. \quad \quad \quad \textbf{if } \text{相容} \textbf{ then 将 } i \text{ 加入 } S \\
& 8. \quad \quad \textbf{if } S \neq \emptyset \textbf{ then} \\
& 9. \quad \quad \quad j \leftarrow \text{Random}(1, |S|) \\
& 10. \quad \quad \quad x_k \leftarrow S[j] \\
& 11. \quad \quad \quad \text{count} \leftarrow \text{count} + 1 \\
& 12. \quad \quad \quad k \leftarrow k + 1 \\
& 13. \quad \quad \textbf{else } k \leftarrow n + 1 \\
& 14. \quad \textbf{return } \text{count}
\end{aligned}
\]
1.4.1 与回溯相结合的改进算法
设 \(\text{stopVegas} \leq n\),表示用 BoolQueen 算法放置的皇后数。剩下 \(n - \text{stopVegas}\) 个皇后用回溯方法放置。
- \(\text{stopVegas} = 0\) 时是完全的回溯算法
- \(\text{stopVegas} = n\) 时是完全的 Las Vegas 算法
算法:QueenLV
\[
\begin{aligned}
& \textbf{算法: } \text{QueenLV}(n) \\
& 1. \quad p \leftarrow \text{BoolQueen}(n) \\
& 2. \quad \textbf{while } p < n \textbf{ do} \\
& 3. \quad \quad p \leftarrow \text{BoolQueen}(n)
\end{aligned}
\]
成功搜索与不成功搜索:
对于不同的 \(\text{stopVegas}\) 值,设:
- \(p\) 为算法成功概率
- \(s\) 为一次成功搜索访问的结点数的平均值
- \(e\) 为一次不成功搜索访问的结点数的平均值
- \(t\) 为算法找到一个解的平均时间
\(n = 12\) 时的统计数据:
| stopVegas |
\(p\) |
\(s\) |
\(e\) |
\(t\) |
| 0 |
1.0000 |
262.00 |
— |
262.00 |
| 5 |
0.5039 |
33.88 |
47.23 |
80.39 |
| 12 |
0.0465 |
13.00 |
10.20 |
222.11 |
结论
\(\text{stopVegas} = 5\) 时算法效率最高。
2 Monte Carlo 型随机算法
2.1 特点
- 这种算法有时会给出 错误的答案
- 其运行时间和出错概率都是随机变量,通常需要分析算法的出错概率
- 多项式时间内运行且出错概率不超过 ⅓ 的随机算法称为有效的 Monte Carlo 型算法
2.2 主元素测试
主元素:出现次数超过一半以上的元素。
算法:Majority
输入:\(n\) 个元素的数组 \(T\)
输出:如果存在主元素则输出 "true",否则 "false"
\[
\begin{aligned}
& \textbf{算法: } \text{Majority}(T, n) \\
& 1. \quad i \leftarrow \text{Random}(1, n) \\
& 2. \quad x \leftarrow T[i] \\
& 3. \quad \text{计数 } x \text{ 在 } T \text{ 中出现的个数 } k \\
& 4. \quad \textbf{if } k > n/2 \textbf{ then return } \text{true} \\
& 5. \quad \textbf{else return } \text{false}
\end{aligned}
\]
算法:BoolMajority
\[
\begin{aligned}
& \textbf{算法: } \text{BoolMajority}(T, n) \\
& 1. \quad \textbf{if } \text{Majority}(T, n) \textbf{ then return } \text{true} \\
& 2. \quad \textbf{else return } \text{Majority}(T, n)
\end{aligned}
\]
算法的正确性:
- 若回答 true:则 \(T\) 存在主元素,算法正确
- 若回答 false:\(T\) 仍可能存在主元素,算法可能出错
- 回答正确概率大于 ½
BoolMajority 算法正确的概率:
| 调用次数 \(k\) |
正确概率大于 |
| 1 |
0.5 |
| 2 |
0.75 |
| 3 |
0.875 |
| 4 |
0.938 |
| 5 |
0.969 |
| 6 |
0.985 |
对于任意给定的 \(\varepsilon > 0\),如果要使出错的概率不超过 \(\varepsilon\),则调用次数 \(k\) 满足:
\[
k \geq \lceil \log_2(1/\varepsilon) \rceil
\]
算法:MCMajority
输入:\(T, n, \varepsilon\)
\[
\begin{aligned}
& \textbf{算法: } \text{MCMajority}(T, n, \varepsilon) \\
& 1. \quad k \leftarrow \lceil \log_2(1/\varepsilon) \rceil \\
& 2. \quad \textbf{for } i \leftarrow 1 \textbf{ to } k \textbf{ do} \\
& 3. \quad \quad \textbf{if } \text{Majority}(T, n) \textbf{ then return } \text{true} \\
& 4. \quad \textbf{return } \text{false}
\end{aligned}
\]
2.3 串相等测试
问题:\(A\) 有一个长串 \(x\),\(B\) 有长串 \(y\),\(A\) 和 \(B\) 希望知道 \(x = y\)?
方法一:\(A\) 将 \(x\) 发送给 \(B\),\(B\) 测试 \(x = y\)。发送消耗大(长串占用信道资源)。
方法二(指纹技术):
- \(A\) 用 \(x\) 导出一个短串 \(f(x)\)(fingerprints)
- \(A\) 将 \(f(x)\) 发送到 \(B\)
- \(B\) 使用同样方法导出相对于 \(y\) 的短串 \(f(y)\)
- \(B\) 比较 \(f(x)\) 与 \(f(y)\)
- 如果 \(f(x) \neq f(y)\),则 \(x \neq y\);如果 \(f(x) = f(y)\),则还不能确定
2.3.1 指纹产生
设 \(x\) 和 \(y\) 的二进制表示对应正整数 \(I(x), I(y)\)。选择素数 \(p\),定义指纹函数:
\[
I_p(x)=I(x)\bmod p
\]
\(A\) 传送 \(p\) 和 \(I_p(x)\) 给 \(B\)。当 \(p\) 不太大时,传送的是短串。
指纹满足:
\[
x=y \Rightarrow I_p(x)=I_p(y)
\]
但反过来不一定成立:
\[
I_p(x)=I_p(y) \nRightarrow x=y
\]
当 \(x\neq y\) 时,一次测试出错的条件是:
\[
p \mid (I(x)-I(y))
\]
2.3.2 随机测试与出错概率
算法:StringEqualityTest
- 随机选择小于 \(M\) 的素数 \(p\)
- \(A\) 发送 \(p\) 和 \(I_p(x)\) 给 \(B\)
- \(B\) 测试是否 \(I_p(x)=I_p(y)\)
若 \(x,y\) 的二进制表示位数为 \(n\),则 \(x,y \leq 2^n\)。如果选择 \(M \geq 2n^2\),一次测试的出错概率不超过:
\[
\frac{|\{p \mid p \text{ 是小于 } 2^n \text{ 的素数,且 } p \mid I(x)-I(y)\}|}{\pi(M)}
\leq \frac{\pi(n)}{\pi(M)}
\approx \frac{n/\ln n}{2n^2/\ln(2n^2)}
\leq \frac{1}{n}
\]
重复执行 \(j\) 次,每次随机选择小于 \(M\) 的素数:
算法:StringTest
输入:\(x,y\),\(n\) 位二进制数
输出:"Yes"(如果 \(x=y\))或 "No"(如果 \(x\neq y\))
- for \(i \leftarrow 1\) to \(j\)
- 随机选择小于 \(M\) 的素数 \(p\)
- \(A\) 发送 \(p\) 和 \(I_p(x)\) 给 \(B\)
- \(B\) 测试
- if \(I_p(x) \neq I_p(y)\) then return "No"
- return "Yes"
令 \(j=\lceil \log \log n\rceil\),则出错概率至多约为:
\[
\left(\frac{1}{n}\right)^j
\]
例如 \(x,y\) 是 \(1{,}000{,}000\) 位二进制数,取 \(M=2\times 10^{12}\),素数 \(p\) 和指纹 \(I_p(x)\) 都至多需要 41 位,因此总共传送约 82 位。
2.4 模式匹配
问题:给定串 \(X\)(\(|X| = n\))和模式 \(Y\)(\(|Y| = m\),\(m \leq n\)),求 \(Y\) 在 \(X\) 中的首次出现位置。
算法一:朴素算法,\(X\) 的首元素对齐,依次从前到后比较 \(X\) 与 \(Y\) 的元素。运行时间 \(O(mn)\)。
算法二:KMP 算法(Knuth, Morris, Pratt),运行时间 \(O(m + n)\)。
算法三(随机算法):
设计思想:设 \(X(j) = x_j x_{j+1} \ldots x_{j+m-1}\),把 \(X(j)\)(\(j = 1, 2, \ldots, n-m+1\))与 \(Y\) 逐个字符的比较,改成对指纹 \(I_p(X(j))\) 与 \(I_p(Y)\) 的比较。
\(X(j)\) 与 \(X(j+1)\) 的关系:
\[
I_p(X(j+1)) = (2 \cdot I_p(X(j)) - W_p \cdot x_j + x_{j+m}) \pmod p
\]
其中 \(W_p = 2^m \pmod p\)。
算法:PatternMatching
输入:串 \(X\) 和 \(Y\),\(|X| = n\),\(|Y| = m\),\(m \leq n\)
输出:如果 \(Y\) 在 \(X\) 中,\(Y\) 出现的第一位置;否则为 "0"
\[
\begin{aligned}
& \textbf{算法: } \text{PatternMatching}(X, Y) \\
& 1. \quad \text{从小于 } M \text{ 的素数集合中随机选择素数 } p \\
& 2. \quad j \leftarrow 1 \\
& 3. \quad W_p \leftarrow 2^m \pmod p \\
& 4. \quad I_p(X(1)) \leftarrow I(X(1)) \pmod p \\
& 5. \quad I_p(Y) \leftarrow I(Y) \pmod p \\
& 6. \quad \textbf{while } j \leq n - m + 1 \textbf{ do} \\
& 7. \quad \quad \textbf{if } I_p(X(j)) = I_p(Y) \textbf{ then return } j \\
& 8. \quad \quad \textbf{if } j = n-m+1 \textbf{ then return } 0 \\
& 9. \quad \quad I_p(X(j+1)) \leftarrow (2 \cdot I_p(X(j)) - W_p \cdot x_j + x_{j+m}) \pmod p \\
& 10. \quad \quad j \leftarrow j + 1 \\
& 11. \quad \textbf{return } 0
\end{aligned}
\]
时间复杂度:\(O(m + n)\)
- \(W_p\)、\(I_p(Y)\)、\(I_p(X(1))\) 计算 \(O(m)\) 时间
- 从 \(I_p(X(j))\) 计算 \(I_p(X(j+1))\) 总共需要 \(O(n)\) 时间
出错条件:\(Y \neq X(j)\),但 \(I_p(Y) = I_p(X(j))\)。等价地:
\[
p \mid \prod_{\{j \mid Y \neq X(j)\}} |I(Y)-I(X(j))|
\]
出错概率:上述乘积大小不超过 \((2^m)^n = 2^{mn}\),整除它的素数个数不超过 \(\pi(mn)\)。选 \(M = 2mn^2\),则出错概率不超过:
\[
\frac{\pi(mn)}{\pi(M)} \approx \frac{mn/\ln(mn)}{2mn^2/\ln(mn^2)} < \frac{1}{n}
\]
3 素数测试
3.1 求幂运算
算法:Exp
求 \(x\) 的 \(m\) 次幂,\(m = d_k d_{k-1} \ldots d_1 d_0\) 为二进制自然数。
\[
\begin{aligned}
& \textbf{算法: } \text{Exp}(x, m) \\
& 1. \quad y \leftarrow 1 \\
& 2. \quad \textbf{for } j \leftarrow k \textbf{ downto } 0 \textbf{ do} \\
& 3. \quad \quad y \leftarrow y^2 \\
& 4. \quad \quad \textbf{if } d_j = 1 \textbf{ then } y \leftarrow x \cdot y \\
& 5. \quad \textbf{return } y
\end{aligned}
\]
算法:ExpMod
求 \(a\) 模 \(n\) 的 \(m\) 次幂,\(m = b_k b_{k-1} \ldots b_1 b_0\) 为二进制自然数。
\[
\begin{aligned}
& \textbf{算法: } \text{ExpMod}(a, m, n) \\
& 1. \quad c \leftarrow 1 \\
& 2. \quad \textbf{for } j \leftarrow k \textbf{ downto } 0 \textbf{ do} \\
& 3. \quad \quad c \leftarrow c^2 \pmod n \\
& 4. \quad \quad \textbf{if } b_j = 1 \textbf{ then } c \leftarrow a \cdot c \pmod n \\
& 5. \quad \textbf{return } c
\end{aligned}
\]
时间复杂度:\(T(n) = O(k \log^2 n) = O(\log^3 n)\)(以位乘作为基本运算)。
3.2 Fermat 小定理
定理:Fermat 小定理
如果 \(n\) 为素数,则对所有的正整数 \(a \not\equiv 0 \pmod n\) 有:
\[
a^{n-1} \equiv 1 \pmod n
\]
素数测试原理:检测 \(2^{n-1} \equiv 1 \pmod n\)。如是,输出 "素数";否则输出 "合数"。
算法:Ptest1
输入:奇整数 \(n\),\(n > 5\)
输出:"prime" 或者 "composite"
\[
\begin{aligned}
& \textbf{算法: } \text{Ptest1}(n) \\
& 1. \quad \textbf{if } \text{ExpMod}(2, n-1, n) = 1 \textbf{ then return } \text{prime} \\
& 2. \quad \textbf{else return } \text{composite}
\end{aligned}
\]
问题
算法 Ptest1 只对 \(a = 2\) 进行测试。如果 \(n\) 为合数且算法输出 "素数",则称 \(n\) 为 基 2 的伪素数。例如 341。
3.3 改进算法
算法:Ptest2
输入:奇整数 \(n\),\(n > 5\)
\[
\begin{aligned}
& \textbf{算法: } \text{Ptest2}(n) \\
& 1. \quad a \leftarrow \text{Random}(2, n-2) \\
& 2. \quad \textbf{if } \text{ExpMod}(a, n-1, n) = 1 \textbf{ then return } \text{prime} \\
& 3. \quad \textbf{else return } \text{composite}
\end{aligned}
\]
Carmichael 数
Fermat 小定理是必要条件,不是充分条件。满足该条件的也可能是合数。对所有与 \(n\) 互素的正整数 \(a\) 都满足条件的合数 \(n\) 称为 Carmichael 数,如 561, 1105, 1729, 2465 等。Carmichael 数非常少,小于 \(10^8\) 的只有 255 个。
由初等数论可以证明:如果 \(n\) 为合数,但不是 Carmichael 数,算法 Ptest2 测试 \(n\) 为合数的概率至少为 ½。
3.4 素数的另一个必要条件
定理
如果 \(n\) 为素数,则方程 \(x^2 \equiv 1 \pmod n\) 的根只有两个,即 \(x = 1\),\(x = -1\)(或 \(x = n-1\))。
证明
\[
x^2 \equiv 1 \pmod n \Leftrightarrow x^2 - 1 \equiv 0 \pmod n \Leftrightarrow (x+1)(x-1) \equiv 0 \pmod n
\]
由于域中没有零因子,\(\Leftrightarrow x+1 \equiv 0\) 或 \(x-1 \equiv 0 \Leftrightarrow x = n-1\) 或 \(x = 1\)。
\[\square\]
称 \(x \neq \pm 1\) 的根为 非平凡的。如果方程有非平凡的根,则 \(n\) 为合数。
例
\(x^2 \pmod{12} \equiv 1 \Leftrightarrow x = 1\) 或 \(x = 11\) 或 \(x = 5\) 或 \(x = 7\)。由于 5 和 7 是非平凡的根,12 是合数。
3.5 Miller-Rabin 算法
设 \(n\) 为奇素数,存在 \(q, m\) 使得 \(n - 1 = 2^q m\)(\(q \geq 1\))。
构造序列:\(a^m \pmod n, a^{2m} \pmod n, \ldots, a^{2^q m} \pmod n\),其最后一项为 \(a^{n-1} \pmod n\),而且每一项是前面一项的平方。
测试方法:
- 对于任意 \(i\)(\(i = 0, 1, \ldots, q-1\)),判断 \(a^{2^i m} \pmod n\) 是否为 1 和 \(n-1\),且它的后一项是否为 1
- 如果其后项为 1,但本项不等于 1 和 \(n-1\),则它就是非平凡的根,从而知道 \(n\) 不是素数
- 随机选择 \(a \in \{2, 3, \ldots, n-1\}\),进行上述测试
算法:findq-m
找 \(q, m\) 使得 \(n - 1 = 2^q m\)。
\[
\begin{aligned}
& \textbf{算法: } \text{findq-m}(n) \\
& 1. \quad q \leftarrow 0; \; m \leftarrow n - 1 \\
& 2. \quad \textbf{repeat} \\
& 3. \quad \quad m \leftarrow m / 2 \\
& 4. \quad \quad q \leftarrow q + 1 \\
& 5. \quad \textbf{until } m \text{ 是奇数}
\end{aligned}
\]
运行时间:\(O(\log n)\)。
算法:test
检测序列是否存在非平凡的根。
\[
\begin{aligned}
& \textbf{算法: } \text{test}(n, q, m) \\
& 1. \quad a \leftarrow \text{Random}(2, n-2) \\
& 2. \quad x_0 \leftarrow \text{ExpMod}(a, m, n) \quad \text{// } x_0 = a^m \pmod n, \; O(\log^3 n) \\
& 3. \quad \textbf{for } i \leftarrow 1 \textbf{ to } q \textbf{ do} \quad \text{// } q = O(\log n) \\
& 4. \quad \quad x_i \leftarrow x_{i-1}^2 \pmod n \quad \text{// } O(\log^2 n) \\
& 5. \quad \quad \textbf{if } x_i = 1 \textbf{ and } x_{i-1} \neq 1 \textbf{ and } x_{i-1} \neq n - 1 \\
& 6. \quad \quad \quad \textbf{then return } \text{composite} \\
& 7. \quad \textbf{if } x_q \neq 1 \textbf{ then return } \text{composite} \\
& 8. \quad \textbf{return } \text{prime}
\end{aligned}
\]
性能分析:
- 1 次测试运行时间 \(O(\log^3 n)\)
- 可证明 1 次测试出错的概率至多 ½
- 重复运行 \(k\) 次,可将出错概率降到至多 \(2^{-k}\)
算法:PrimalityTest(Miller-Rabin)
输入:奇整数 \(n \geq 5\)
\[
\begin{aligned}
& \textbf{算法: } \text{PrimalityTest}(n) \\
& 1. \quad \text{findq-m}(n) \\
& 2. \quad k \leftarrow \lceil \log n \rceil \\
& 3. \quad \textbf{for } i \leftarrow 1 \textbf{ to } k \textbf{ do} \\
& 4. \quad \quad \textbf{if } \text{test}(n, q, m) = \text{composite} \textbf{ then return } \text{composite} \\
& 5. \quad \textbf{return } \text{prime}
\end{aligned}
\]
时间:\(T(n) = O(\log^4 n)\)(按位乘统计)。
令 \(k = \lceil \log n \rceil\),出错的概率小于等于 \(2^{-k} \leq 1/n\)。因此如果 \(n\) 为素数,则算法输出 "prime";如果 \(n\) 为合数,则算法以至少 \(1-1/n\) 的概率输出 "composite"。
4 随机算法的分类与局限性
4.1 Las Vegas 型 vs Monte Carlo 型
| 特性 |
Las Vegas 型 |
Monte Carlo 型 |
| 解的正确性 |
若得到解,总是正确 |
有时会给出错误答案 |
| 运行时间 |
随机变量 |
随机变量 |
| 出错概率 |
0(可能无解) |
大于 0 |
| 有效算法定义 |
期望运行时间是多项式且总是正确 |
多项式时间内运行且出错概率不超过 ⅓ |
Monte Carlo 型随机算法的错误类型:
| 错误类型 |
含义 |
例子 |
| 弃真型单侧错误 |
宣布接受时一定正确,宣布拒绝时可能错误 |
主元素测试 |
| 取伪型单侧错误 |
宣布拒绝时一定正确,宣布接受时可能错误 |
素数测试 |
| 双侧错误 |
接受和拒绝都可能出错 |
一般 Monte Carlo 算法 |
常见随机复杂性类:
| 类 |
含义 |
| ZPP |
零错误概率多项式时间算法,即有效 Las Vegas 算法 |
| BPP |
错误概率有界的多项式时间随机算法 |
| RP |
弃真型单侧错误概率有界的有效算法 |
| coRP |
取伪型单侧错误概率有界的有效算法 |
局限性
错误概率有界的多项式时间随机算法不太可能解决 NP 完全问题。
4.2 处理难解问题的策略
4.2.1 对问题施加限制
有些 NP 完全问题在限制输入结构后会变成多项式时间可解问题。
| 问题 |
属于 \(P\) 的限制 |
仍为 NPC 的限制 |
| 2SAT / HornSAT |
2SAT、HornSAT |
一般 SAT |
| VC |
最大度 \(D \leq 2\) |
最大度 \(D \geq 3\) |
| HC |
最大度 2 |
最大度 3 |
| 顶点三着色 |
最大度 3 |
最大度 4 |
| 反馈顶点集 |
最大度 2 |
最大度 3 |
| 团 |
给定最大度 \(D\) |
任意图 |
4.2.2 固定参数算法
固定参数算法:输入中带有一个参数 \(k\),当输入规模为 \(n\) 时运行时间为 \(O(f(k) \cdot n^c)\) 的算法。
例:顶点覆盖的固定参数算法
VC:给定图 \(G\),正整数 \(K\),问是否存在不超过 \(K\) 的顶点覆盖?
固定常数 \(k\),输入为 \((G, k)\)。穷举所有 \(k\) 元顶点子集,看看是否存在顶点覆盖。算法复杂度大约是 \(O(kn \cdot C_n^k) = O(kn^{k+1})\)。存在 \(O(2^k \cdot kn)\) 的算法。
4.2.3 改进的指数时间算法
\(O^*\) 表示忽略了多项式因子,如 \(O^*(2^n) = O(n^{O(1)} 2^n)\)。
- 蛮力算法为 \(O^*(2^n)\) 时,对任何 \(1 < c < 2\),\(O^*(c^n)\) 称为 非平凡的指数时间算法
- 可证明在 \(O^*(1.8393^n)\) 时间内正确求解 3-SAT
- 指数时间假设:对每个正整数 \(k\),都存在常数 \(c_k > 0\),使得求解 \(k\)-SAT 的精确算法时间复杂性不低于 \(\Omega^*(2^{c_k n})\)
4.2.4 其他策略
| 策略 |
说明 |
| 启发式方法 |
目前无法从理论上给出性能保证,但实践效果良好;包括回溯与分支限界法、局部搜索法、随机化策略、重启策略、模拟退火、遗传算法等 |
| 平均情况复杂度 |
有些 NP 完全问题在平均复杂性度量下是易解的,例如哈密顿回路问题在 \(G(n,1/2)\) 上有 \(O(n^3)\) 时间算法 |
| 难解算例生成 |
确定紧的实例 |
| 消息传递算法 |
基于统计物理的方法 |
5 总结
| 主题 |
核心内容 |
| Las Vegas 型 |
随机快速排序、随机选择、随机 n 后放置 |
| Monte Carlo 型 |
主元素测试、串相等测试、模式匹配 |
| 素数测试 |
Fermat 小定理、Miller-Rabin 算法 |
| 处理策略 |
固定参数算法、指数时间算法、启发式方法 |