从确定性到随机性
在经典算法设计中,我们习惯于追求确定性的正确答案。然而,许多看似简单的问题在确定性框架下却有着不可逾越的复杂度下界。随机化为我们提供了突破这些下界的可能——只要允许极小的错误概率,就能获得确定性算法无法企及的效率。
本讲的核心概念是 fingerprinting (指纹技术),一种贯穿随机算法设计的基本范式。
什么是 Fingerprinting
Fingerprinting 的核心思想是:不直接比较两个庞大的对象,而是将它们映射为短小的「指纹」,通过比较指纹来间接判断相等性。
Fingerprinting 的形式化定义
一个 fingerprinting 方案是一个(随机化的)函数 FING : U → V \text{FING}\colon \mathcal{U} \to \mathcal{V} FING : U → V ,其中 ∣ V ∣ ≪ ∣ U ∣ |\mathcal{V}| \ll |\mathcal{U}| ∣ V ∣ ≪ ∣ U ∣ ,满足:
无假阴性 :a = b ⟹ FING ( a ) = FING ( b ) a = b \implies \text{FING}(a) = \text{FING}(b) a = b ⟹ FING ( a ) = FING ( b ) (确定性保证)
假阳性概率小 :a ≠ b ⟹ Pr [ FING ( a ) = FING ( b ) ] a \neq b \implies \Pr[\text{FING}(a) = \text{FING}(b)] a = b ⟹ Pr [ FING ( a ) = FING ( b )] 很小
指纹短小 :FING ( a ) \text{FING}(a) FING ( a ) 的表示长度远小于 a a a 本身
性质 1 保证了单边错误 (one-sided error):当算法判定「不等」时一定正确,只在判定「相等」时可能犯错(假阳性)。
这一思想贯穿本讲所有内容——从多项式恒等检验、通信复杂性中的相等性问题,到矩阵乘法验证和字符串匹配,fingerprinting 都扮演着关键角色。
多项式恒等检验
问题定义
多项式恒等检验 (Polynomial Identity Testing, PIT )是代数计算中的一个基本问题:给定两个多项式 P P P 和 Q Q Q (以算术电路的形式表示),判断它们是否计算同一个多项式,即 P ≡ Q P \equiv Q P ≡ Q 。等价地,令 Q = P 1 − P 2 Q = P_1 - P_2 Q = P 1 − P 2 ,问题转化为判断 Q Q Q 是否为零多项式。
算术电路
在 PIT 中,多项式不是以展开形式(如 3 x 2 + 2 x + 1 3x^2 + 2x + 1 3 x 2 + 2 x + 1 )给出的——因为展开后可能有指数多个项,无法显式列出。多项式的输入形式是算术电路 (Arithmetic Circuit),它描述的不是多项式「长什么样」,而是如何从变量和常数出发,通过一系列加、减、乘操作一步步算出它。
算术电路
算术电路是一个有向无环图(DAG),其中:
输入节点 (叶节点)标记为变量 x 1 , x 2 , … x_1, x_2, \ldots x 1 , x 2 , … 或常数
内部节点 标记为 + + + 、− - − 或 × \times × 运算
有一个指定的输出节点 ,其计算结果即为电路所表示的多项式
flowchart BT
x1["x₁"] --> plus1["+"]
y1["y₁"] --> plus1
x2["x₂"] --> plus2["+"]
y2["y₂"] --> plus2
xn["xₙ"] --> plusn["+"]
yn["yₙ"] --> plusn
plus1 --> mul["× · · · ×"]
plus2 --> mul
plusn --> mul
mul --> out(("输出"))
classDef var fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
classDef op fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
classDef output fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px
class x1,y1,x2,y2,xn,yn var
class plus1,plus2,plusn,mul op
class out output
算术电路的关键特性在于它可以指数级压缩 多项式的表示。例如:
∏ i = 1 n ( x i + y i ) \prod_{i=1}^{n} (x_i + y_i)
i = 1 ∏ n ( x i + y i )
这个电路的描述长度仅为 O ( n ) O(n) O ( n ) ,但展开后有 2 n 2^n 2 n 个单项式。因此,将多项式显式展开再逐项比较系数在计算上是不可行的——我们需要一种能直接在电路表示上工作的算法。
PIT 问题至今没有已知的高效确定性算法,这是计算复杂性理论中的一个重大未解问题。如果存在多项式时间的确定性 PIT 算法,则意味着 NEXP ≠ P/poly \textsf{NEXP} \neq \textsf{P/poly} NEXP = P/poly 或 # P ≠ FP \#\textsf{P} \neq \textsf{FP} # P = FP ——这两个都是尚未被证明的重大复杂性分离猜想。
Schwartz-Zippel 引理
PIT 有一个优雅的随机化解法,其核心是以下引理:
Schwartz-Zippel 引理
设 Q ( x 1 , x 2 , … , x n ) Q(x_1, x_2, \ldots, x_n) Q ( x 1 , x 2 , … , x n ) 是域 F \mathbb{F} F 上的一个非零多项式,总次数 (total degree)为 d d d 。设 S S S 是 F \mathbb{F} F 的一个有限子集。若 r 1 , r 2 , … , r n r_1, r_2, \ldots, r_n r 1 , r 2 , … , r n 独立均匀地从 S S S 中随机选取,则
Pr [ Q ( r 1 , r 2 , … , r n ) = 0 ] ⩽ d ∣ S ∣ \Pr[Q(r_1, r_2, \ldots, r_n) = 0] \le \frac{d}{|S|}
Pr [ Q ( r 1 , r 2 , … , r n ) = 0 ] ⩽ ∣ S ∣ d
这个结论非常惊人:无论多项式有多少个变量、结构多复杂,只要在一个足够大的集合中随机取值,非零多项式求值为零的概率就很小 。而且这个界只依赖于多项式的总次数和取值集合的大小,与变量个数 n n n 完全无关。
这里需要注意总次数 和个体次数 (individual degree)的区别。总次数是所有单项式中变量幂次之和的最大值。例如 x 1 2 x 2 3 + x 1 x 3 4 x_1^2 x_2^3 + x_1 x_3^4 x 1 2 x 2 3 + x 1 x 3 4 的总次数为 max ( 2 + 3 , 1 + 4 ) = 5 \max(2+3, 1+4) = 5 max ( 2 + 3 , 1 + 4 ) = 5 。
证明
对变量个数 n n n 进行归纳。
基础情形 (n = 1 n = 1 n = 1 ):单变量多项式 Q ( x 1 ) Q(x_1) Q ( x 1 ) 的次数为 d d d ,由代数基本定理(或更一般地,域上多项式的性质),它至多有 d d d 个根。因此:
Pr [ Q ( r 1 ) = 0 ] ⩽ d ∣ S ∣ \Pr[Q(r_1) = 0] \le \frac{d}{|S|}
Pr [ Q ( r 1 ) = 0 ] ⩽ ∣ S ∣ d
归纳步骤 :假设引理对 n − 1 n-1 n − 1 个变量成立。将 Q Q Q 按 x 1 x_1 x 1 的幂次展开:
Q ( x 1 , x 2 , … , x n ) = ∑ i = 0 k x 1 i ⋅ Q i ( x 2 , … , x n ) Q(x_1, x_2, \ldots, x_n) = \sum_{i=0}^{k} x_1^i \cdot Q_i(x_2, \ldots, x_n)
Q ( x 1 , x 2 , … , x n ) = i = 0 ∑ k x 1 i ⋅ Q i ( x 2 , … , x n )
其中 k ⩽ d k \le d k ⩽ d 是 x 1 x_1 x 1 在 Q Q Q 中出现的最高次数,Q k ( x 2 , … , x n ) Q_k(x_2, \ldots, x_n) Q k ( x 2 , … , x n ) 是非零多项式(作为 x 1 k x_1^k x 1 k 的系数)。注意 Q k Q_k Q k 的总次数至多为 d − k d - k d − k ,因为 Q Q Q 中包含 x 1 k x_1^k x 1 k 的任何单项式,其余变量的次数之和至多为 d − k d - k d − k 。
利用全概率公式。令事件 A A A 为「Q k ( r 2 , … , r n ) = 0 Q_k(r_2, \ldots, r_n) = 0 Q k ( r 2 , … , r n ) = 0 」,事件 B B B 为「Q ( r 1 , r 2 , … , r n ) = 0 Q(r_1, r_2, \ldots, r_n) = 0 Q ( r 1 , r 2 , … , r n ) = 0 」:
Pr [ B ] = Pr [ B ∣ A ] ⋅ Pr [ A ] + Pr [ B ∣ A ˉ ] ⋅ Pr [ A ˉ ] \Pr[B] = \Pr[B \mid A] \cdot \Pr[A] + \Pr[B \mid \bar{A}] \cdot \Pr[\bar{A}]
Pr [ B ] = Pr [ B ∣ A ] ⋅ Pr [ A ] + Pr [ B ∣ A ˉ ] ⋅ Pr [ A ˉ ]
由归纳假设,Q k Q_k Q k 是 n − 1 n-1 n − 1 个变量的非零多项式,总次数 ⩽ d − k \le d - k ⩽ d − k ,故 Pr [ A ] ⩽ d − k ∣ S ∣ \Pr[A] \le \dfrac{d - k}{|S|} Pr [ A ] ⩽ ∣ S ∣ d − k
当 A ˉ \bar{A} A ˉ 发生时,即 Q k ( r 2 , … , r n ) ≠ 0 Q_k(r_2, \ldots, r_n) \neq 0 Q k ( r 2 , … , r n ) = 0 。此时将 r 2 , … , r n r_2, \ldots, r_n r 2 , … , r n 的值代入,Q ( x 1 , r 2 , … , r n ) Q(x_1, r_2, \ldots, r_n) Q ( x 1 , r 2 , … , r n ) 成为关于 x 1 x_1 x 1 的单变量多项式,且因为 x 1 k x_1^k x 1 k 的系数 Q k ( r 2 , … , r n ) ≠ 0 Q_k(r_2, \ldots, r_n) \neq 0 Q k ( r 2 , … , r n ) = 0 ,它确实是一个次数为 k k k 的非零多项式。由基础情形,Pr [ B ∣ A ˉ ] ⩽ k ∣ S ∣ \Pr[B \mid \bar{A}] \le \dfrac{k}{|S|} Pr [ B ∣ A ˉ ] ⩽ ∣ S ∣ k
由此:
Pr [ B ] ⩽ 1 ⋅ d − k ∣ S ∣ + k ∣ S ∣ ⋅ 1 = d ∣ S ∣ \Pr[B] \le 1 \cdot \frac{d - k}{|S|} + \frac{k}{|S|} \cdot 1 = \frac{d}{|S|}
Pr [ B ] ⩽ 1 ⋅ ∣ S ∣ d − k + ∣ S ∣ k ⋅ 1 = ∣ S ∣ d
应用于 PIT
要检验 Q ≡ 0 Q \equiv 0 Q ≡ 0 ,只需从足够大的集合 S S S 中随机选取一个点 ( r 1 , … , r n ) (r_1, \ldots, r_n) ( r 1 , … , r n ) ,利用算术电路计算 Q ( r 1 , … , r n ) Q(r_1, \ldots, r_n) Q ( r 1 , … , r n ) :
若结果 ≠ 0 \neq 0 = 0 :Q Q Q 一定不是零多项式(确定性结论)
若结果 = 0 = 0 = 0 :Q Q Q 大概率是零多项式,但有至多 d / ∣ S ∣ d/|S| d /∣ S ∣ 的假阳性概率
这正是 fingerprinting 的范式:FING ( Q ) = Q ( r 1 , … , r n ) \text{FING}(Q) = Q(r_1, \ldots, r_n) FING ( Q ) = Q ( r 1 , … , r n ) ,将一个可能有指数多项的多项式压缩为一个域元素。
降低错误概率
通过独立重复 t t t 次检验(每次独立随机选取新的取值点),错误概率降低到 ( d / ∣ S ∣ ) t (d/|S|)^t ( d /∣ S ∣ ) t 。选取 ∣ S ∣ ⩾ 2 d |S| \ge 2d ∣ S ∣ ⩾ 2 d 即可使单次错误概率 ⩽ 1 / 2 \le 1/2 ⩽ 1/2 ,重复 t t t 次后错误概率 ⩽ 2 − t \le 2^{-t} ⩽ 2 − t ,指数级衰减。
Schwartz-Zippel 引理的应用远不止 PIT 。它还可以用于判断图是否有完美匹配、验证矩阵乘法、检验有根树同构、分析 Reed-Muller 码的距离性质、构造概率可检验证明(PCP)等。本讲后续的几个应用都是它的直接推论。
通信复杂性与相等性问题
问题模型
通信复杂性 (Communication Complexity)研究以下场景:Alice 持有输入 a a a ,Bob 持有输入 b b b ,他们需要通过通信来协作计算某个函数 f ( a , b ) f(a, b) f ( a , b ) 。通信复杂度衡量的是完成计算所需的最小通信比特数(在最坏情况下)。
考虑最基本的相等性问题 (Equality):Alice 有一个 n n n 比特字符串 a ∈ { 0 , 1 } n a \in \{0,1\}^n a ∈ { 0 , 1 } n ,Bob 有一个 n n n 比特字符串 b ∈ { 0 , 1 } n b \in \{0,1\}^n b ∈ { 0 , 1 } n ,他们需要判断 a = b a = b a = b 是否成立。
flowchart LR
A["Alice<br/>持有 a ∈ {0,1}ⁿ"] -- "交换消息" --> B["Bob<br/>持有 b ∈ {0,1}ⁿ"]
B -- "a = b?" --> C["输出"]
classDef person fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
classDef output fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px
class A,B person
class C output
确定性下界
在确定性协议中,相等性问题的确定性通信复杂度为 Θ ( n ) \Theta(n) Θ ( n ) ——Alice 和 Bob 必须交换线性于 n n n 的比特数。
直观理解 :如果 Alice 发送的消息总共不到 n n n 比特(比如只有 k < n k < n k < n 比特),那么她的 2 n 2^n 2 n 种可能输入中必有两个不同输入产生了相同的消息。对于这两个输入,Bob 收到相同的消息,无法区分它们,因此至少对其中一个给出错误答案。
这个直觉可以用组合矩形 (Combinatorial Rectangle)的语言严格化。
组合矩形
想象一个 2 n × 2 n 2^n \times 2^n 2 n × 2 n 的表格,行对应 Alice 的所有可能输入 a a a ,列对应 Bob 的所有可能输入 b b b ,格子 ( a , b ) (a, b) ( a , b ) 标记为 f ( a , b ) f(a,b) f ( a , b ) 的值。
确定性协议中,每个叶节点(输出节点)对应的输入集合构成一个组合矩形 R × C R \times C R × C ,其中 R ⊆ { 0 , 1 } n R \subseteq \{0,1\}^n R ⊆ { 0 , 1 } n 是使 Alice 到达该叶节点的输入集合,C ⊆ { 0 , 1 } n C \subseteq \{0,1\}^n C ⊆ { 0 , 1 } n 是使 Bob 到达该叶节点的输入集合。
为什么是笛卡尔积的形状?因为 Alice 发送的消息只取决于她自己的输入 a a a ,Bob 发送的消息也只取决于他自己的输入 b b b 。如果两个不同的输入 a 1 , a 2 a_1, a_2 a 1 , a 2 让 Alice 产生完全相同的消息序列,那么无论 Bob 的输入 b b b 是什么,( a 1 , b ) (a_1, b) ( a 1 , b ) 和 ( a 2 , b ) (a_2, b) ( a 2 , b ) 都会走到同一个叶节点——因为 Bob 看到的交互完全一样。因此到达同一叶节点的输入集合必然是 R × C R \times C R × C 的形式。
一个正确的协议要求每个矩形内的所有输入都有相同的正确输出。
现在将这一工具应用于相等函数。所有使 f ( a , b ) = 1 f(a,b) = 1 f ( a , b ) = 1 (即 a = b a = b a = b )的输入恰好是对角线 { ( a , a ) : a ∈ { 0 , 1 } n } \{(a,a) : a \in \{0,1\}^n\} {( a , a ) : a ∈ { 0 , 1 } n } ——共 2 n 2^n 2 n 个点。关键观察:对角线上的每个组合矩形最多只包含 1 个点 。
为什么?假设某个标记为「相等」的矩形 R × C R \times C R × C 包含两个不同的对角线点 ( a 1 , a 1 ) (a_1, a_1) ( a 1 , a 1 ) 和 ( a 2 , a 2 ) (a_2, a_2) ( a 2 , a 2 ) (a 1 ≠ a 2 a_1 \ne a_2 a 1 = a 2 )。那么 a 1 , a 2 ∈ R a_1, a_2 \in R a 1 , a 2 ∈ R 且 a 1 , a 2 ∈ C a_1, a_2 \in C a 1 , a 2 ∈ C ,由笛卡尔积的性质,( a 1 , a 2 ) (a_1, a_2) ( a 1 , a 2 ) 也在这个矩形中。但 a 1 ≠ a 2 a_1 \ne a_2 a 1 = a 2 ,所以 ( a 1 , a 2 ) (a_1, a_2) ( a 1 , a 2 ) 应该输出「不等」——与该矩形标记为「相等」矛盾。
因此,协议至少需要 2 n 2^n 2 n 个标记为「相等」的叶节点来覆盖所有 2 n 2^n 2 n 个对角线点,决策树至少有 2 n 2^n 2 n 个叶节点,通信量 ⩾ log 2 2 n = n \ge \log_2 2^n = n ⩾ log 2 2 n = n 。
随机化协议
随机化可以将通信复杂度从 Θ ( n ) \Theta(n) Θ ( n ) 大幅降低到 O ( log n ) O(\log n) O ( log n ) 。根据随机性是共享的还是私有的,有两种不同的协议。
公共随机协议
在公共随机 (public coin)模型中,Alice 和 Bob 共享一个随机源(如一个公开的随机比特串),但各自的输入是私有的。
模运算与域
后续频繁使用 Z p \mathbb{Z}_p Z p :这是模素数 p p p 的整数集合 { 0 , 1 , … , p − 1 } \{0, 1, \ldots, p-1\} { 0 , 1 , … , p − 1 } ,加法和乘法都在模 p p p 下进行。例如在 Z 7 \mathbb{Z}_7 Z 7 中,3 + 5 = 1 , 3 × 4 = 5 3 + 5 = 1,\, 3 \times 4 = 5 3 + 5 = 1 , 3 × 4 = 5 。当 p p p 为素数时,每个非零元素都有乘法逆元,因此 Z p \mathbb{Z}_p Z p 构成一个域 (Field)——支持加减乘除。Z p [ x ] \mathbb{Z}_p[x] Z p [ x ] 表示系数在 Z p \mathbb{Z}_p Z p 中的多项式。
将 a ∈ { 0 , 1 } n a \in \{0,1\}^n a ∈ { 0 , 1 } n 编码为多项式 f a ( x ) = ∑ i = 1 n a i ⋅ x i ∈ Z p [ x ] f_a(x) = \sum_{i=1}^{n} a_i \cdot x^i \in \mathbb{Z}_p[x] f a ( x ) = ∑ i = 1 n a i ⋅ x i ∈ Z p [ x ] ,其中 p p p 是一个公开的素数(p = Θ ( n 2 ) p = \Theta(n^2) p = Θ ( n 2 ) )。类似地,Bob 将 b b b 编码为 f b ( x ) f_b(x) f b ( x ) 。
协议 :
Alice 和 Bob 共享随机元素 r ∈ Z p r \in \mathbb{Z}_p r ∈ Z p
Alice 计算 f a ( r ) = ∑ i = 1 n a i ⋅ r i m o d p f_a(r) = \sum_{i=1}^{n} a_i \cdot r^i \bmod p f a ( r ) = ∑ i = 1 n a i ⋅ r i mod p ,发送给 Bob
Bob 计算 f b ( r ) = ∑ i = 1 n b i ⋅ r i m o d p f_b(r) = \sum_{i=1}^{n} b_i \cdot r^i \bmod p f b ( r ) = ∑ i = 1 n b i ⋅ r i mod p ,检查 f a ( r ) = f b ( r ) f_a(r) = f_b(r) f a ( r ) = f b ( r )
通信量仅为 O ( log p ) = O ( log n ) O(\log p) = O(\log n) O ( log p ) = O ( log n ) 比特(Alice 发送一个 Z p \mathbb{Z}_p Z p 中的元素)。
错误分析 :若 a ≠ b a \neq b a = b ,则 f a − f b f_a - f_b f a − f b 是 Z p [ x ] \mathbb{Z}_p[x] Z p [ x ] 上次数 ⩽ n \le n ⩽ n 的非零多项式。由 Schwartz-Zippel 引理:
Pr [ f a ( r ) = f b ( r ) ] ⩽ n p \Pr[f_a(r) = f_b(r)] \le \frac{n}{p}
Pr [ f a ( r ) = f b ( r )] ⩽ p n
取 p = Θ ( n 2 ) p = \Theta(n^2) p = Θ ( n 2 ) ,错误概率 ⩽ 1 / n \le 1/n ⩽ 1/ n 。
另一种更极端的公共随机协议只需 1 比特 通信:Alice 和 Bob 共享随机向量 r ∈ { 0 , 1 } n \bm{r} \in \{0,1\}^n r ∈ { 0 , 1 } n ,Alice 发送 ⟨ a , r ⟩ m o d 2 \langle a, \bm{r} \rangle \bmod 2 ⟨ a , r ⟩ mod 2 (内积模 2),Bob 检查是否等于 ⟨ b , r ⟩ m o d 2 \langle b, \bm{r} \rangle \bmod 2 ⟨ b , r ⟩ mod 2 。若 a ≠ b a \neq b a = b ,则 ⟨ a − b , r ⟩ m o d 2 \langle a - b, \bm{r} \rangle \bmod 2 ⟨ a − b , r ⟩ mod 2 是一个关于 r \bm{r} r 的非零线性多项式(因为 a − b a - b a − b 有某个分量非零),由 Schwartz-Zippel 引理(d = 1 , ∣ S ∣ = 2 d = 1,\, |S| = 2 d = 1 , ∣ S ∣ = 2 ),碰撞概率 ⩽ 1 / 2 \le 1/2 ⩽ 1/2 。单次错误概率较高,但重复几十次即可将错误概率降到任意小。
这里的 fingerprint 是 FING ( a ) = f a ( r ) = ∑ a i ⋅ r i m o d p \text{FING}(a) = f_a(r) = \sum a_i \cdot r^i \bmod p FING ( a ) = f a ( r ) = ∑ a i ⋅ r i mod p ——将 n n n 比特的字符串压缩为一个 O ( log n ) O(\log n) O ( log n ) 比特的域元素。
私有随机协议
在私有随机 (private coin)模型中,Alice 和 Bob 各自拥有独立的随机源,不共享随机性。
将 a , b ∈ { 0 , 1 } n a, b \in \{0,1\}^n a , b ∈ { 0 , 1 } n 视为 [ 0 , 2 n ) [0, 2^n) [ 0 , 2 n ) 中的整数。
协议 :
Alice 从不超过 k k k 的素数中均匀随机选取一个素数 p p p (k k k 待定)
Alice 将 ( p , a m o d p ) (p, \, a \bmod p) ( p , a mod p ) 发送给 Bob
Bob 检查 a m o d p ≡ b m o d p a \bmod p \equiv b \bmod p a mod p ≡ b mod p ,输出结果
通信量为 O ( log k ) = O ( log n ) O(\log k) = O(\log n) O ( log k ) = O ( log n ) 比特。这里的 fingerprint 是 FING p ( a ) = a m o d p \text{FING}_p(a) = a \bmod p FING p ( a ) = a mod p 。
私有随机协议的错误分析
若 a = b a = b a = b ,则 a m o d p = b m o d p a \bmod p = b \bmod p a mod p = b mod p 一定成立,不会产生假阴性。
若 a ≠ b a \neq b a = b ,令 z = ∣ a − b ∣ z = |a - b| z = ∣ a − b ∣ ,则 0 < z < 2 n 0 < z < 2^n 0 < z < 2 n 。假阳性发生当且仅当 p ∣ z p \mid z p ∣ z 。我们需要估计随机素数 p p p 整除 z z z 的概率。
关键观察:z z z 的不同素因子个数是有限的。由于 z < 2 n z < 2^n z < 2 n ,而最小的 n n n 个素数的乘积满足 2 × 3 × 5 × ⋯ × p n ⩾ 2 n 2 \times 3 \times 5 \times \cdots \times p_n \ge 2^n 2 × 3 × 5 × ⋯ × p n ⩾ 2 n (素数阶乘 primorial 的增长速度),若 z z z 有 n n n 个或更多不同素因子,则 z z z 至少等于前 n n n 个素数之积,即 z ⩾ 2 n z \ge 2^n z ⩾ 2 n ,与 z < 2 n z < 2^n z < 2 n 矛盾。因此 z z z 至多有 n − 1 n - 1 n − 1 个不同的素因子。
素数计数函数与素数定理
由素数定理 (Prime Number Theorem),不超过 N N N 的素数个数满足
π ( N ) ∼ N ln N ( N → ∞ ) \pi(N) \sim \frac{N}{\ln N} \quad (N \to \infty)
π ( N ) ∼ ln N N ( N → ∞ )
这意味着 [ 1 , k ] [1, k] [ 1 , k ] 范围内约有 k ln k \dfrac{k}{\ln k} ln k k 个素数。
对于我们的分析,更有用的一个推论是:对于足够大的 N N N ,π ( N ) ⩾ N 2 ln N \pi(N) \ge \dfrac{N}{2\ln N} π ( N ) ⩾ 2 ln N N 。
错误概率为:
Pr [ error ] = # { p ⩽ k : p 是素数且 p ∣ z } π ( k ) ⩽ n − 1 π ( k ) ≈ n ln k k \Pr[\text{error}] = \frac{\#\{p \le k : p \text{ 是素数且 } p \mid z\}}{\pi(k)} \le \frac{n - 1}{\pi(k)} \approx \frac{n \ln k}{k}
Pr [ error ] = π ( k ) # { p ⩽ k : p 是素数且 p ∣ z } ⩽ π ( k ) n − 1 ≈ k n ln k
选取 k = n 3 k = n^3 k = n 3 :
Pr [ error ] ⩽ n ⋅ 3 ln n n 3 = 3 ln n n 2 = O ( 1 n ) \Pr[\text{error}] \le \frac{n \cdot 3\ln n}{n^3} = \frac{3\ln n}{n^2} = O\left(\frac{1}{n}\right)
Pr [ error ] ⩽ n 3 n ⋅ 3 ln n = n 2 3 ln n = O ( n 1 )
注意 fingerprint 函数 FING p ( a ) = a m o d p \text{FING}_p(a) = a \bmod p FING p ( a ) = a mod p 是一个随机化的映射——随机性来自素数 p p p 的选择。两种协议使用了不同的 fingerprinting 方案:公共随机协议基于多项式求值和 Schwartz-Zippel 引理,私有随机协议基于模运算和素数定理,但它们的共同点是将 n n n 比特的信息压缩为 O ( log n ) O(\log n) O ( log n ) 比特的指纹。
Newman 定理
Newman 定理
公共随机和私有随机两种模型的通信复杂度之间有什么关系?显然私有随机不弱于公共随机(后者可以模拟前者),因为若有一个 private-coin 协议 Π \Pi Π ,其中 Alice 和 Bob 分别使用独立随机串 R A , R B R_{A}, R_{B} R A , R B ,那么构造 public-coin 协议 Π ′ \Pi' Π ′ :
取公共随机串 R = ( R A , R B ) R=\left(R_{A}, R_{B}\right) R = ( R A , R B )
Alice 在 Π ′ \Pi' Π ′ 中把 R A R_{A} R A 当作自己原来的私有随机性
Bob 在 Π ′ \Pi' Π ′ 中把 R B R_{B} R B 当作自己原来的私有随机性
则 Π ′ \Pi' Π ′ 对任意输入 ( x , y ) (x, y) ( x , y ) 的行为分布与 Π \Pi Π 相同。因此
R p u b ( f ) ⩽ R p r i v ( f ) R^{\mathrm{pub}}(f) \le R^{\mathrm{priv}}(f)
R pub ( f ) ⩽ R priv ( f )
即 public-coin 的随机通信复杂度不大于 private-coin。
但反过来呢?
Newman 定理
对于任意函数 f f f ,令 R ϵ pub ( f ) R^{\text{pub}}_\epsilon(f) R ϵ pub ( f ) 和 R ϵ priv ( f ) R^{\text{priv}}_\epsilon(f) R ϵ priv ( f ) 分别表示错误概率至多为 ϵ \epsilon ϵ 的公共随机和私有随机通信复杂度。则:
R ϵ priv ( f ) ⩽ R ϵ pub ( f ) + O ( log n ) R^{\text{priv}}_\epsilon(f) \le R^{\text{pub}}_\epsilon(f) + O(\log n)
R ϵ priv ( f ) ⩽ R ϵ pub ( f ) + O ( log n )
Newman 定理告诉我们,私有随机最多比公共随机多 O ( log n ) O(\log n) O ( log n ) 的通信量 。
其证明思想如下:假设已有一个公共随机协议 Π \Pi Π ,使用公共随机串 s s s ,错误概率 ⩽ ϵ \le \epsilon ⩽ ϵ 。虽然可能的随机串有指数多个,但我们并不需要所有的——只需从中挑选出 t = poly ( n ) t = \text{poly}(n) t = poly ( n ) 个「有代表性的」随机串 s 1 , … , s t s_1, \ldots, s_t s 1 , … , s t 即可。通过概率论中的抽样论证,可以证明随机选取 t t t 个串后,对所有输入对 ( a , b ) (a,b) ( a , b ) 的平均错误率与使用全部随机串时接近。
有了这组串,Alice 和 Bob 事先约定好 s 1 , … , s t s_1, \ldots, s_t s 1 , … , s t (这不需要通信,因为是协议的一部分)。协议开始时,Alice 用私有随机性选取 i ∈ [ t ] i \in [t] i ∈ [ t ] ,将 i i i 发送给 Bob(需要 ⌈ log 2 t ⌉ = O ( log n ) \lceil \log_2 t \rceil = O(\log n) ⌈ log 2 t ⌉ = O ( log n ) 比特),双方随后使用 s i s_i s i 执行原协议。额外通信开销仅为 O ( log n ) O(\log n) O ( log n ) 。
对于相等性问题,两种模型的通信复杂度都是 Θ ( log n ) \Theta(\log n) Θ ( log n ) ,差距在常数因子内。
应用:二部图完美匹配
问题与经典方法
给定一个二部图 (Bipartite Graph)G = ( U , V , E ) G = (U, V, E) G = ( U , V , E ) ,其中 ∣ U ∣ = ∣ V ∣ = n |U| = |V| = n ∣ U ∣ = ∣ V ∣ = n ,判断 G G G 是否存在完美匹配 (Perfect Matching),即一个边集 M ⊆ E M \subseteq E M ⊆ E ,使得 U U U 和 V V V 中的每个顶点都恰好被 M M M 中的一条边覆盖。
二部图与完美匹配
二部图 是指顶点可以分成两组 U U U 和 V V V ,且所有边都跨组连接(组内没有边)的图。完美匹配 是一种配对方案:将 U U U 中每个顶点恰好与 V V V 中一个顶点配对,且每个顶点恰好被配对一次(要求 ∣ U ∣ = ∣ V ∣ |U| = |V| ∣ U ∣ = ∣ V ∣ )。
一个直观例子:n n n 个学生和 n n n 门课程,每个学生只对部分课程感兴趣(用边表示)。完美匹配就是给每个学生恰好分配一门他感兴趣的课,且每门课恰好分配给一个学生。不是所有二部图都有完美匹配——可能有些学生竞争同一门课,导致无法全部满足。
经典的确定性算法基于增广路径(从一个未匹配的顶点出发,沿交替使用匹配边和非匹配边的路径扩展当前匹配):如 Hopcroft-Karp 算法,时间复杂度为 O ( m n ) O(m\sqrt{n}) O ( m n ) ,其中 m = ∣ E ∣ m = |E| m = ∣ E ∣ 。利用 fingerprinting 和代数方法,可以得到一个截然不同的随机判定算法。
Edmonds 定理与 Edmonds 矩阵
Edmonds 定理 (Edmonds' Theorem)建立了图的匹配与矩阵行列式之间的深刻联系,将组合问题转化为代数问题。
定义二部图 G G G 的 Edmonds 矩阵 M \bm{M} M 为 n × n n \times n n × n 矩阵,其中每条边对应一个独立的形式变量:
M i j = { x i j if ( u i , v j ) ∈ E 0 otherwise M_{ij} = \begin{cases} x_{ij} & \text{if } (u_i, v_j) \in E \\ 0 & \text{otherwise} \end{cases}
M ij = { x ij 0 if ( u i , v j ) ∈ E otherwise
其中 { x i j } \{x_{ij}\} { x ij } 是相互独立的形式变量 (indeterminates)——它们不是具体的数值,而是纯粹的符号占位符。可以把每个 x i j x_{ij} x ij 理解为边 ( u i , v j ) (u_i, v_j) ( u i , v j ) 的「标签」:行列式 det ( M ) \det(\bm{M}) det ( M ) 就成为一个关于这些标签的多项式。使用形式变量而非具体数值,是为了让不同的边保持可区分——这样不同匹配对应的乘积项涉及不同的变量组合,彼此不会相消。后面的随机算法就是给这些变量随机赋值,然后利用 Schwartz-Zippel 引理检验行列式是否恒为零。
具体例子
考虑一个 3 × 3 3 \times 3 3 × 3 的二部图,U = { u 1 , u 2 , u 3 } , V = { v 1 , v 2 , v 3 } U = \{u_1, u_2, u_3\},\, V = \{v_1, v_2, v_3\} U = { u 1 , u 2 , u 3 } , V = { v 1 , v 2 , v 3 } ,边集 E = { ( u 1 , v 1 ) , ( u 1 , v 2 ) , ( u 2 , v 1 ) , ( u 2 , v 3 ) , ( u 3 , v 2 ) , ( u 3 , v 3 ) } E = \{(u_1,v_1), (u_1,v_2), (u_2,v_1), (u_2,v_3), (u_3,v_2), (u_3,v_3)\} E = {( u 1 , v 1 ) , ( u 1 , v 2 ) , ( u 2 , v 1 ) , ( u 2 , v 3 ) , ( u 3 , v 2 ) , ( u 3 , v 3 )} 。Edmonds 矩阵为:
M = ( x 11 x 12 0 x 21 0 x 23 0 x 32 x 33 ) \bm{M} = \begin{pmatrix} x_{11} & x_{12} & 0 \\ x_{21} & 0 & x_{23} \\ 0 & x_{32} & x_{33} \end{pmatrix}
M = x 11 x 21 0 x 12 0 x 32 0 x 23 x 33
行列式展开后,6 个排列中只有对应完美匹配的排列贡献非零项。例如排列 σ = ( 1 , 2 , 3 ) \sigma = (1,2,3) σ = ( 1 , 2 , 3 ) (恒等排列)对应匹配 { ( u 1 , v 1 ) , ( u 2 , v 2 ) , ( u 3 , v 3 ) } \{(u_1,v_1),(u_2,v_2),(u_3,v_3)\} {( u 1 , v 1 ) , ( u 2 , v 2 ) , ( u 3 , v 3 )} ,但 M 2 , 2 = 0 M_{2,2} = 0 M 2 , 2 = 0 ,所以这个排列贡献为零。排列 σ = ( 1 , 3 , 2 ) \sigma = (1,3,2) σ = ( 1 , 3 , 2 ) 对应 { ( u 1 , v 1 ) , ( u 2 , v 3 ) , ( u 3 , v 2 ) } \{(u_1,v_1),(u_2,v_3),(u_3,v_2)\} {( u 1 , v 1 ) , ( u 2 , v 3 ) , ( u 3 , v 2 )} ,所有边都存在,贡献 − x 11 x 23 x 32 -x_{11}x_{23}x_{32} − x 11 x 23 x 32 。排列 σ = ( 2 , 1 , 3 ) \sigma = (2,1,3) σ = ( 2 , 1 , 3 ) 对应 { ( u 1 , v 2 ) , ( u 2 , v 1 ) , ( u 3 , v 3 ) } \{(u_1,v_2),(u_2,v_1),(u_3,v_3)\} {( u 1 , v 2 ) , ( u 2 , v 1 ) , ( u 3 , v 3 )} ,贡献 − x 12 x 21 x 33 -x_{12}x_{21}x_{33} − x 12 x 21 x 33 。因此 det ( M ) = − x 11 x 23 x 32 − x 12 x 21 x 33 ≢ 0 \det(\bm{M}) = -x_{11}x_{23}x_{32} - x_{12}x_{21}x_{33} \not\equiv 0 det ( M ) = − x 11 x 23 x 32 − x 12 x 21 x 33 ≡ 0 ,说明该图有完美匹配。
对于一般图(非二部图),对应的概念是 Tutte 矩阵 ,定义为反对称矩阵:
T i j = { x i j if ( i , j ) ∈ E and i < j − x i j if ( i , j ) ∈ E and i > j 0 if ( i , j ) ∉ E or i = j T_{ij} = \begin{cases} x_{ij} & \text{if } (i,j) \in E \text{ and } i < j \\ -x_{ij} & \text{if } (i,j) \in E \text{ and } i > j \\ 0 & \text{if } (i,j) \notin E \text{ or } i = j \end{cases}
T ij = ⎩ ⎨ ⎧ x ij − x ij 0 if ( i , j ) ∈ E and i < j if ( i , j ) ∈ E and i > j if ( i , j ) ∈ / E or i = j
Edmonds 矩阵可以看作 Tutte 矩阵在二部图上的简化版本。Edmonds 定理同样适用于一般图:G G G 有完美匹配当且仅当其 Tutte 矩阵的行列式(作为形式变量的多项式)不恒为零。
Edmonds 定理
二部图 G G G 存在完美匹配,当且仅当 det ( M ) \det(\bm{M}) det ( M ) 作为 { x i j } \{x_{ij}\} { x ij } 的多项式不恒为零。
为什么 Edmonds 定理成立
行列式的定义为:
det ( M ) = ∑ σ ∈ S n sgn ( σ ) ∏ i = 1 n M i , σ ( i ) \det(\bm{M}) = \sum_{\sigma \in S_n} \operatorname{sgn}(\sigma) \prod_{i=1}^{n} M_{i,\sigma(i)}
det ( M ) = σ ∈ S n ∑ sgn ( σ ) i = 1 ∏ n M i , σ ( i )
其中求和遍历所有 n ! n! n ! 个排列 σ ∈ S n \sigma \in S_n σ ∈ S n ,sgn ( σ ) ∈ { + 1 , − 1 } \operatorname{sgn}(\sigma) \in \{+1, -1\} sgn ( σ ) ∈ { + 1 , − 1 } 是排列的符号(偶排列取 + 1 +1 + 1 ,奇排列取 − 1 -1 − 1 )。每个排列 σ \sigma σ 对应 U U U 到 V V V 的一个一一映射:将 u i u_i u i 映射到 v σ ( i ) v_{\sigma(i)} v σ ( i ) 。
乘积 ∏ i = 1 n M i , σ ( i ) \prod_{i=1}^{n} M_{i,\sigma(i)} ∏ i = 1 n M i , σ ( i ) 非零当且仅当对所有 i i i 都有 ( u i , v σ ( i ) ) ∈ E (u_i, v_{\sigma(i)}) \in E ( u i , v σ ( i ) ) ∈ E ,即 { ( u i , v σ ( i ) ) : i = 1 , … , n } \{(u_i, v_{\sigma(i)}) : i = 1, \ldots, n\} {( u i , v σ ( i ) ) : i = 1 , … , n } 构成 G G G 的一个完美匹配。
若 G G G 没有 完美匹配,则行列式中每一项的乘积都包含至少一个零因子,故 det ( M ) ≡ 0 \det(\bm{M}) \equiv 0 det ( M ) ≡ 0
若 G G G 有 完美匹配 σ ∗ \sigma^* σ ∗ ,则对应项 sgn ( σ ∗ ) ∏ i x i , σ ∗ ( i ) \operatorname{sgn}(\sigma^*) \prod_{i} x_{i,\sigma^*(i)} sgn ( σ ∗ ) ∏ i x i , σ ∗ ( i ) 是一个非零的单项式。关键在于,由于各 x i j x_{ij} x ij 是独立的形式变量,不同匹配对应的单项式一定不同 (因为它们涉及不同的变量子集),所以非零项之间不会相消,det ( M ) \det(\bm{M}) det ( M ) 作为多项式不恒为零
随机算法
Edmonds 定理将完美匹配的存在性归结为多项式是否恒为零,而这正是 PIT 问题。结合 Schwartz-Zippel 引理,得到如下算法:
将每个形式变量 x i j x_{ij} x ij 独立均匀地替换为 S = { 1 , 2 , … , 2 n } S = \{1, 2, \ldots, 2n\} S = { 1 , 2 , … , 2 n } 中的随机值
计算数值矩阵的行列式(高斯消元 O ( n 3 ) O(n^3) O ( n 3 ) ,或利用矩阵乘法算法 O ( n ω ) O(n^\omega) O ( n ω ) )
若行列式为 0 0 0 ,输出「无完美匹配」;否则输出「有完美匹配」
det ( M ) \det(\bm{M}) det ( M ) 的总次数为 n n n (每个乘积项恰好是 n n n 个变量之积),取 ∣ S ∣ = 2 n |S| = 2n ∣ S ∣ = 2 n 。由 Schwartz-Zippel 引理,当存在完美匹配时,随机赋值后行列式恰好为零的概率 ⩽ n / ( 2 n ) = 1 / 2 \le n/(2n) = 1/2 ⩽ n / ( 2 n ) = 1/2 。
这个算法虽然在判定问题上并不比 Hopcroft-Karp 更快,但它揭示了匹配问题与线性代数之间的深刻联系。更重要的是,这一代数方法可以推广到并行算法 :计算行列式可以高效并行化(属于复杂性类 NC \textsf{NC} NC ,即可以用多项式个处理器在 O ( polylog n ) O(\operatorname{polylog} n) O ( polylog n ) 即 O ( ( log n ) k ) O\left((\log n)^k\right) O ( ( log n ) k ) 时间内完成),因此二部图完美匹配判定也可以随机并行化(属于 RNC \textsf{RNC} RNC )——这是经典增广路径方法难以达到的。
一个至今未解的问题是:完美匹配判定是否可以确定性并行化(即属于 NC \textsf{NC} NC )?目前只知道它在 RNC \textsf{RNC} RNC 中,去随机化仍然是一个重大挑战。
应用:矩阵乘法验证
问题背景
给定三个 n × n n \times n n × n 矩阵 A , B , C \bm{A}, \bm{B}, \bm{C} A , B , C ,判断是否 A B = C \bm{A}\bm{B} = \bm{C} A B = C 。
直接计算 A B \bm{A}\bm{B} A B 再逐项比较需要矩阵乘法的时间。令 ω \omega ω 为矩阵乘法指数,即 n × n n \times n n × n 矩阵乘法的最优时间复杂度为 O ( n ω ) O(n^\omega) O ( n ω ) 。长期以来,降低 ω \omega ω 的上界是算法理论的核心课题之一:
年份
作者
ω \omega ω 上界
-
朴素算法
3 3 3
1969
Strassen
2.807 2.807 2.807
…
…
…
2024
Williams, Xu, Xu, Zhou
2.3716 2.3716 2.3716
目前 ω > 2 \omega > 2 ω > 2 仍然成立。长期以来广泛猜想 ω = 2 \omega = 2 ω = 2 ,但近年来也有研究者开始质疑这一猜想。无论如何,验证 A B = C \bm{AB} = \bm{C} AB = C 似乎理应比计算 A B \bm{AB} AB 更容易——事实上,Freivalds 给出了一个 O ( n 2 ) O(n^2) O ( n 2 ) 的随机验证算法。
Freivalds 算法
Freivalds 算法 的核心思想是对矩阵做 fingerprinting:FING ( M ) = M r \text{FING}(\bm{M}) = \bm{M}\bm{r} FING ( M ) = M r ,将一个 n × n n \times n n × n 的矩阵压缩为一个 n n n 维向量。
随机选取向量 r ∈ { 0 , 1 } n \bm{r} \in \{0,1\}^n r ∈ { 0 , 1 } n ,每个分量独立均匀地取 0 0 0 或 1 1 1
计算 A ( B r ) \bm{A}(\bm{B}\bm{r}) A ( B r ) 和 C r \bm{C}\bm{r} C r
若 A ( B r ) ≠ C r \bm{A}(\bm{B}\bm{r}) \neq \bm{C}\bm{r} A ( B r ) = C r ,输出「A B ≠ C \bm{AB} \neq \bm{C} AB = C 」;否则输出「A B = C \bm{AB} = \bm{C} AB = C 」
计算顺序
步骤 2 中必须先计算 B r \bm{B}\bm{r} B r (矩阵乘向量,O ( n 2 ) O(n^2) O ( n 2 ) ),再计算 A \bm{A} A 乘以结果(又一次矩阵乘向量,O ( n 2 ) O(n^2) O ( n 2 ) )。若直接计算 ( A B ) r (\bm{A}\bm{B})\bm{r} ( A B ) r ,则 A B \bm{A}\bm{B} A B 本身就是矩阵乘法,退化为 O ( n ω ) O(n^\omega) O ( n ω ) 。总计算量为 O ( n 2 ) O(n^2) O ( n 2 ) 。
正确性分析
令 D = A B − C \bm{D} = \bm{AB} - \bm{C} D = AB − C 。算法检验的等价条件是 D r = 0 \bm{D}\bm{r} = \bm{0} D r = 0 。
若 D = 0 \bm{D} = \bm{0} D = 0 (即 A B = C \bm{AB} = \bm{C} AB = C ),则 D r = 0 \bm{D}\bm{r} = \bm{0} D r = 0 恒成立,算法不会出错。
若 D ≠ 0 \bm{D} \neq \bm{0} D = 0 ,我们需要证明 Pr [ D r = 0 ] ⩽ 1 / 2 \Pr[\bm{D}\bm{r} = \bm{0}] \le 1/2 Pr [ D r = 0 ] ⩽ 1/2 。
由于 D ≠ 0 \bm{D} \neq \bm{0} D = 0 ,存在某个非零行,不妨设第 i i i 行 d i ≠ 0 \bm{d}_i \neq \bm{0} d i = 0 ,且 d i j ≠ 0 d_{ij} \neq 0 d ij = 0 。考虑 ( D r ) i (\bm{D}\bm{r})_i ( D r ) i :
( D r ) i = ∑ k = 1 n d i k r k = d i j r j + ∑ k ≠ j d i k r k ⏟ ≔ W (\bm{D}\bm{r})_i = \sum_{k=1}^{n} d_{ik} r_k = d_{ij} r_j + \underbrace{\sum_{k \neq j} d_{ik} r_k}_{\coloneqq\, W}
( D r ) i = k = 1 ∑ n d ik r k = d ij r j + : = W k = j ∑ d ik r k
这里使用了延迟决策原则 (Principle of Deferred Decisions):我们可以假设先确定所有 r k r_k r k (k ≠ j k \neq j k = j )的值,再考虑 r j r_j r j 的选择。一旦 r k r_k r k (k ≠ j k \neq j k = j )固定,W W W 就成为一个确定的常数,于是:
( D r ) i = 0 ⟺ r j = − W d i j (\bm{D}\bm{r})_i = 0 \iff r_j = -\frac{W}{d_{ij}}
( D r ) i = 0 ⟺ r j = − d ij W
无论 W W W 的值是什么,( D r ) i = 0 (\bm{D}\bm{r})_i = 0 ( D r ) i = 0 等价于 d i j r j + W = 0 d_{ij} r_j + W = 0 d ij r j + W = 0 ,即 r j r_j r j 必须取某个特定值。而 r j r_j r j 在 { 0 , 1 } \{0,1\} { 0 , 1 } 上均匀分布且独立于其他 r k r_k r k ,{ 0 , 1 } \{0,1\} { 0 , 1 } 只有两个元素,所以 r j r_j r j 恰好命中那个特定值的概率至多为 1 / 2 1/2 1/2 (如果那个值不在 { 0 , 1 } \{0,1\} { 0 , 1 } 中,概率为 0 0 0 )。
也可以从计数的角度看:满足 D r = 0 \bm{D}\bm{r} = \bm{0} D r = 0 的 r ∈ { 0 , 1 } n \bm{r} \in \{0,1\}^n r ∈ { 0 , 1 } n 至多有 2 n − 1 2^{n-1} 2 n − 1 个(因为每组固定的 r − j r_{-j} r − j ,即除了 r j r_j r j 后其余分量的集合,至多对应一个 r j r_j r j 的取值,至多有一个满足条件),而 r \bm{r} r 的总选取数为 2 n 2^n 2 n ,所以:
Pr [ D r = 0 ] ⩽ 2 n − 1 2 n = 1 2 \Pr[\bm{D}\bm{r} = \bm{0}] \le \frac{2^{n-1}}{2^n} = \frac{1}{2}
Pr [ D r = 0 ] ⩽ 2 n 2 n − 1 = 2 1
独立重复 t t t 次(每次独立随机选取 r \bm{r} r ),错误概率降为 2 − t 2^{-t} 2 − t ,总时间 O ( t n 2 ) O(tn^2) O ( t n 2 ) 。取 t = O ( log n ) t = O(\log n) t = O ( log n ) ,即可在 O ( n 2 log n ) O(n^2 \log n) O ( n 2 log n ) 时间内以高概率得到正确结果。
Schwartz-Zippel 视角
Freivalds 算法也可以从 Schwartz-Zippel 引理的角度统一理解。将 ( D r ) i = ∑ k d i k r k (\bm{D}\bm{r})_i = \sum_k d_{ik} r_k ( D r ) i = ∑ k d ik r k 看作变量 r 1 , … , r n r_1, \ldots, r_n r 1 , … , r n 的多元多项式,它是一个总次数为 1 1 1 的多项式。若它不恒为零,由 Schwartz-Zippel 引理(d = 1 , ∣ S ∣ = 2 d = 1,\, |S| = 2 d = 1 , ∣ S ∣ = 2 ),在 S = { 0 , 1 } S = \{0,1\} S = { 0 , 1 } 上随机取值为零的概率 ⩽ 1 / ∣ S ∣ = 1 / 2 \le 1/|S| = 1/2 ⩽ 1/∣ S ∣ = 1/2 。
Karp-Rabin 字符串匹配
问题定义
模式匹配 (Pattern Matching)是字符串算法中的经典问题:给定文本串 T [ 1 … n ] T[1 \ldots n] T [ 1 … n ] 和模式串 P [ 1 … m ] P[1 \ldots m] P [ 1 … m ] (m ⩽ n m \le n m ⩽ n ),找到 P P P 在 T T T 中所有出现的位置,即所有满足 T [ j … j + m − 1 ] = P T[j \ldots j+m-1] = P T [ j … j + m − 1 ] = P 的位置 j j j 。
朴素算法逐位置对齐并逐字符比较,最坏时间 O ( n m ) O(nm) O ( nm ) 。确定性线性算法(如 KMP、Boyer-Moore)可以达到 O ( n + m ) O(n + m) O ( n + m ) ,但需要预处理模式串,空间 O ( m ) O(m) O ( m ) 。
通用框架:Fingerprinting 方法
在介绍具体算法之前,先看 fingerprinting 方法解决模式匹配的一般框架:
计算模式的指纹 FING ( P ) \text{FING}(P) FING ( P )
对每个位置 j j j ,计算子串的指纹 FING ( T j ) \text{FING}(T_j) FING ( T j ) (其中 T j = T [ j … j + m − 1 ] T_j = T[j \ldots j+m-1] T j = T [ j … j + m − 1 ] )
比较 FING ( T j ) \text{FING}(T_j) FING ( T j ) 与 FING ( P ) \text{FING}(P) FING ( P )
这个框架要求指纹函数满足一个额外条件:增量可计算性 ——能够从 FING ( T j ) \text{FING}(T_j) FING ( T j ) 在 O ( 1 ) O(1) O ( 1 ) 时间内递推出 FING ( T j + 1 ) \text{FING}(T_{j+1}) FING ( T j + 1 ) 。这是因为如果每个位置都从头计算指纹,总时间仍为 O ( n m ) O(nm) O ( nm ) ,没有改进。
Karp-Rabin 算法
Karp-Rabin 算法 给出了一个满足增量可计算性的 fingerprinting 方案。
将二进制字符串 s = s 1 s 2 … s m s = s_1 s_2 \ldots s_m s = s 1 s 2 … s m 视为整数 s ˉ = ∑ i = 1 m s i ⋅ 2 m − i \bar{s} = \sum_{i=1}^{m} s_i \cdot 2^{m-i} s ˉ = ∑ i = 1 m s i ⋅ 2 m − i 。定义指纹:
FING p ( s ) = s ˉ m o d p \text{FING}_p(s) = \bar{s} \bmod p
FING p ( s ) = s ˉ mod p
其中 p p p 是从不超过 m n 3 mn^3 m n 3 的素数中均匀随机选取的素数。
滑动窗口与增量更新
关键观察:相邻位置的子串 T j T_j T j 和 T j + 1 T_{j+1} T j + 1 高度重叠,仅相差首尾各一个字符。在整数表示下:
T ˉ j + 1 = 2 ( T ˉ j − T [ j ] ⋅ 2 m − 1 ) + T [ j + m ] \bar{T}_{j+1} = 2\big(\bar{T}_j - T[j] \cdot 2^{m-1}\big) + T[j+m]
T ˉ j + 1 = 2 ( T ˉ j − T [ j ] ⋅ 2 m − 1 ) + T [ j + m ]
直觉很简单:从 T j T_j T j 到 T j + 1 T_{j+1} T j + 1 ,去掉最高位 T [ j ] T[j] T [ j ] ,其余位左移一位(乘以 2 2 2 ),再加上新的最低位 T [ j + m ] T[j+m] T [ j + m ] 。
由于模运算与加法、乘法兼容(即 ( a + b ) m o d p = ( ( a m o d p ) + ( b m o d p ) ) m o d p (a + b) \bmod p = ((a \bmod p) + (b \bmod p)) \bmod p ( a + b ) mod p = (( a mod p ) + ( b mod p )) mod p ,乘法同理),同一递推关系在模 p p p 下也成立:
FING p ( T j + 1 ) = ( 2 ⋅ ( FING p ( T j ) − T [ j ] ⋅ 2 m − 1 ) + T [ j + m ] ) m o d p \text{FING}_p(T_{j+1}) = \big(2 \cdot (\text{FING}_p(T_j) - T[j] \cdot 2^{m-1}) + T[j+m]\big) \bmod p
FING p ( T j + 1 ) = ( 2 ⋅ ( FING p ( T j ) − T [ j ] ⋅ 2 m − 1 ) + T [ j + m ] ) mod p
只需预计算 2 m − 1 m o d p 2^{m-1} \bmod p 2 m − 1 mod p ,之后每次更新只涉及 O ( 1 ) O(1) O ( 1 ) 次模运算。
算法流程
flowchart LR
A["随机选取素数 p ≤ mn³"] --> B["预计算 FING(P) 和 FING(T₁)<br/>以及 2^(m-1) mod p"]
B --> C{"FING(T_j) = FING(P)?"}
C -- 是 --> D["报告位置 j 匹配"]
C -- 否 --> E["跳过"]
D --> F{"j < n - m + 1?"}
E --> F
F -- 是 --> G["O(1) 递推 FING(T_{j+1})"]
G --> C
F -- 否 --> H["结束"]
classDef init fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
classDef decision fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
classDef match fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px
classDef skip fill:#f8f9fa,stroke:#495057,stroke-width:2px
classDef endclass fill:#ffebee,stroke:#c62828,stroke-width:2px
class A,B init
class C,F decision
class D match
class E,G skip
class H endclass
复杂度 :
时间:预处理 O ( m ) O(m) O ( m ) ,匹配阶段每步 O ( 1 ) O(1) O ( 1 ) ,共 n − m + 1 n - m + 1 n − m + 1 步,总计 O ( n ) O(n) O ( n )
空间:O ( log ( m n ) ) O(\log(mn)) O ( log ( mn )) ——只需存储当前指纹、素数 p p p 、预计算的 2 m − 1 m o d p 2^{m-1} \bmod p 2 m − 1 mod p
错误分析
对于某个固定位置 j j j ,若 T j ≠ P T_j \neq P T j = P ,假阳性发生当且仅当 p ∣ ( T ˉ j − P ˉ ) p \mid (\bar{T}_j - \bar{P}) p ∣ ( T ˉ j − P ˉ ) 。令 z j = ∣ T ˉ j − P ˉ ∣ z_j = |\bar{T}_j - \bar{P}| z j = ∣ T ˉ j − P ˉ ∣ ,则 0 < z j < 2 m 0 < z_j < 2^m 0 < z j < 2 m ,所以 z j z_j z j 至多有 m m m 个不同的素因子(理由同前)。
Pr [ 位置 j 假阳性 ] = # { p ⩽ m n 3 : p 是素数且 p ∣ z j } π ( m n 3 ) ⩽ m π ( m n 3 ) ≈ m ⋅ ln ( m n 3 ) m n 3 \Pr[\text{位置 } j \text{ 假阳性}] = \frac{\#\{p \le mn^3 : p \text{ 是素数且 } p \mid z_j\}}{\pi(mn^3)} \le \frac{m}{\pi(mn^3)} \approx \frac{m \cdot \ln(mn^3)}{mn^3}
Pr [ 位置 j 假阳性 ] = π ( m n 3 ) # { p ⩽ m n 3 : p 是素数且 p ∣ z j } ⩽ π ( m n 3 ) m ≈ m n 3 m ⋅ ln ( m n 3 )
这里有 n − m + 1 ⩽ n n - m + 1 \le n n − m + 1 ⩽ n 个位置需要检查。由联合界 (union bound:多个事件中至少一个发生的概率不超过各自概率之和,即 Pr [ ⋃ i A i ] ⩽ ∑ i Pr [ A i ] \Pr[\bigcup_i A_i] \le \sum_i \Pr[A_i] Pr [ ⋃ i A i ] ⩽ ∑ i Pr [ A i ] ):
Pr [ 存在假阳性 ] ⩽ n ⋅ m ⋅ ln ( m n 3 ) m n 3 = ln ( m n 3 ) n 2 = O ( log n n 2 ) = O ( 1 n ) \Pr[\text{存在假阳性}] \le n \cdot \frac{m \cdot \ln(mn^3)}{mn^3} = \frac{\ln(mn^3)}{n^2} = O\left(\frac{\log n}{n^2}\right) = O\left(\frac{1}{n}\right)
Pr [ 存在假阳性 ] ⩽ n ⋅ m n 3 m ⋅ ln ( m n 3 ) = n 2 ln ( m n 3 ) = O ( n 2 log n ) = O ( n 1 )
Karp-Rabin 的优势
与 KMP 等确定性算法相比,Karp-Rabin 的主要优势在于:
实现极简 :核心仅涉及模运算,无需复杂的预处理数据结构
空间极小 :仅需 O ( log n ) O(\log n) O ( log n ) 空间,远小于 KMP 的 O ( m ) O(m) O ( m )
泛化能力强 :天然适用于多模式匹配(同时搜索多个模式串)、二维模式匹配、以及大字母表上的匹配问题
数据流友好 :文本可以逐字符流式输入,无需预先存储
一般字母表
上述描述假设二进制字母表 { 0 , 1 } \{0,1\} { 0 , 1 } 。对于大小为 ∣ Σ ∣ |\Sigma| ∣Σ∣ 的一般字母表,只需将 2 2 2 替换为 ∣ Σ ∣ |\Sigma| ∣Σ∣ :将字符串视为 ∣ Σ ∣ |\Sigma| ∣Σ∣ 进制数,递推公式变为 FING p ( T j + 1 ) = ( ∣ Σ ∣ ⋅ ( FING p ( T j ) − T [ j ] ⋅ ∣ Σ ∣ m − 1 ) + T [ j + m ] ) m o d p \text{FING}_p(T_{j+1}) = (|\Sigma| \cdot (\text{FING}_p(T_j) - T[j] \cdot |\Sigma|^{m-1}) + T[j+m]) \bmod p FING p ( T j + 1 ) = ( ∣Σ∣ ⋅ ( FING p ( T j ) − T [ j ] ⋅ ∣Σ ∣ m − 1 ) + T [ j + m ]) mod p 。分析完全类似。
多重集相等性检验与元素唯一性
问题定义
给定一个序列 A = ( a 1 , a 2 , … , a n ) A = (a_1, a_2, \ldots, a_n) A = ( a 1 , a 2 , … , a n ) ,其中 a i ∈ [ n ] = { 1 , 2 , … , n } a_i \in [n] = \{1, 2, \ldots, n\} a i ∈ [ n ] = { 1 , 2 , … , n } ,判断 A A A 中的元素是否两两不同(元素唯一性问题 ,Checking Distinctness)。
等价地,如果元素两两不同,则 A A A 恰好是 { 1 , 2 , … , n } \{1, 2, \ldots, n\} { 1 , 2 , … , n } 的一个排列。因此问题可以表述为:判断多重集 (Multiset)A A A 是否等于集合 I = { 1 , 2 , … , n } I = \{1, 2, \ldots, n\} I = { 1 , 2 , … , n } (作为多重集相等)。
排序后逐个比较需要 O ( n log n ) O(n \log n) O ( n log n ) 时间。哈希表方法需要 O ( n ) O(n) O ( n ) 时间但空间也是 O ( n ) O(n) O ( n ) 。利用 fingerprinting,可以在 O ( n ) O(n) O ( n ) 时间、O ( log n ) O(\log n) O ( log n ) 空间内完成——这在数据流模型下尤为重要。
多项式编码
将多重集编码为多项式是 Lipton 的核心思想。定义:
f A ( x ) = ∏ i = 1 n ( x − a i ) f I ( x ) = ∏ i = 1 n ( x − i ) f_A(x) = \prod_{i=1}^{n} (x - a_i) \qquad f_I(x) = \prod_{i=1}^{n} (x - i)
f A ( x ) = i = 1 ∏ n ( x − a i ) f I ( x ) = i = 1 ∏ n ( x − i )
f A f_A f A 和 f I f_I f I 都是 R \R R 上的首一(最高次系数为 1)n n n 次多项式。A A A 中元素两两不同(且均在 [ n ] [n] [ n ] 中),当且仅当 f A ≡ f I f_A \equiv f_I f A ≡ f I 。这是因为首一多项式可以唯一分解为 ∏ ( x − r i ) \prod (x - r_i) ∏ ( x − r i ) ,其根集合(含重数)完全确定了这个多项式。
定义指纹:
FING ( A ) = f A ( r ) m o d p = ∏ i = 1 n ( r − a i ) m o d p \text{FING}(A) = f_A(r) \bmod p = \prod_{i=1}^{n} (r - a_i) \bmod p
FING ( A ) = f A ( r ) mod p = i = 1 ∏ n ( r − a i ) mod p
其中参数 r r r 和 p p p 的选取需要仔细设计。
两类错误源
当 A A A 中有重复元素时(即 f A ≢ f I f_A \not\equiv f_I f A ≡ f I 在 R \R R 上),假阳性 FING ( A ) = FING ( I ) \text{FING}(A) = \text{FING}(I) FING ( A ) = FING ( I ) 可以由两个不同的原因引起:
两层随机性
仅用随机素数 p p p (固定 r r r )或仅用随机取值点 r r r (固定 p p p )都不足以保证低错误概率。需要同时随机化 r r r 和 p p p 。
错误源 1:f A ≡ f I f_A \equiv f_I f A ≡ f I 在 Z p \mathbb{Z}_p Z p 上
虽然 f A ≠ f I f_A \neq f_I f A = f I 在 R \R R 上,但有可能在取模 p p p 之后两个多项式变得相同。这发生在 p p p 整除 f A − f I f_A - f_I f A − f I 的某个非零系数的时候。
设 f A ( x ) − f I ( x ) = ∑ k = 0 n c k x k f_A(x) - f_I(x) = \sum_{k=0}^{n} c_k x^k f A ( x ) − f I ( x ) = ∑ k = 0 n c k x k ,其中 c k ∈ Z c_k \in \mathbb{Z} c k ∈ Z 且不全为零。每个系数 ∣ c k ∣ |c_k| ∣ c k ∣ 至多为 ( n k ) ⋅ n k ⩽ n n \binom{n}{k} \cdot n^k \le n^n ( k n ) ⋅ n k ⩽ n n (a i ∈ [ n ] a_i \in [n] a i ∈ [ n ] ,选择 k k k 个元素的组合数乘以每个元素的最大值 n n n 的 k k k 次方)。素因子至少为 2,因此 c k c_k c k 的不同素因子个数至多为:
log 2 ∣ c k ∣ = ln ∣ c k ∣ ln 2 ⩽ n ln n ln 2 = O ( n log n ) \log_2 |c_k| = \frac{\ln |c_k|}{\ln 2} \le \frac{n \ln n}{\ln 2} = O(n \log n)
log 2 ∣ c k ∣ = ln 2 ln ∣ c k ∣ ⩽ ln 2 n ln n = O ( n log n )
错误源 2:f A ≢ f I f_A \not\equiv f_I f A ≡ f I 在 Z p \mathbb{Z}_p Z p 上,但 f A ( r ) ≡ f I ( r ) ( m o d p ) f_A(r) \equiv f_I(r) \pmod{p} f A ( r ) ≡ f I ( r ) ( mod p )
此时 g ( x ) = f A ( x ) − f I ( x ) g(x) = f_A(x) - f_I(x) g ( x ) = f A ( x ) − f I ( x ) 作为 Z p \mathbb{Z}_p Z p 上的多项式不恒为零,次数至多为 n n n 。由 Schwartz-Zippel 引理(或直接由域上多项式的根的个数),随机 r ∈ Z p r \in \mathbb{Z}_p r ∈ Z p 满足 g ( r ) ≡ 0 ( m o d p ) g(r) \equiv 0 \pmod{p} g ( r ) ≡ 0 ( mod p ) 的概率至多为 n / p n/p n / p 。
Lipton 算法与参数选择
Lipton 算法 (Lipton's Algorithm)的具体参数如下:
随机选取素数 p p p ,满足 ( n log n ) 2 2 ⩽ p ⩽ ( n log n ) 2 \dfrac{(n\log n)^2}{2} \le p \le (n\log n)^2 2 ( n log n ) 2 ⩽ p ⩽ ( n log n ) 2
随机选取 r ∈ Z p r \in \mathbb{Z}_p r ∈ Z p
计算 FING ( A ) = ∏ i = 1 n ( r − a i ) m o d p \text{FING}(A) = \prod_{i=1}^{n} (r - a_i) \bmod p FING ( A ) = ∏ i = 1 n ( r − a i ) mod p
计算 FING ( I ) = ∏ i = 1 n ( r − i ) m o d p \text{FING}(I) = \prod_{i=1}^{n} (r - i) \bmod p FING ( I ) = ∏ i = 1 n ( r − i ) mod p
检查 FING ( A ) = FING ( I ) \text{FING}(A) = \text{FING}(I) FING ( A ) = FING ( I )
参数范围的选取
选取素数范围为 [ L , U ] [L, U] [ L , U ] (其中 L = ( n log n ) 2 / 2 , U = ( n log n ) 2 L = (n\log n)^2/2,\, U = (n\log n)^2 L = ( n log n ) 2 /2 , U = ( n log n ) 2 ),而非从 [ 1 , U ] [1, U] [ 1 , U ] 中选取,是为了保证所有素数都足够大,从而控制错误源 2。
由素数定理,区间 [ L , U ] [L, U] [ L , U ] 中的素数个数约为:
π ( U ) − π ( L ) ≈ U ln U − L ln L ≈ L ln L = Θ ( ( n log n ) 2 log ( n log n ) ) = Θ ( n 2 ( log n ) 2 log n ) = Θ ( n 2 log n ) \pi(U) - \pi(L) \approx \frac{U}{\ln U} - \frac{L}{\ln L} \approx \frac{L}{\ln L} = \Theta\left(\frac{(n\log n)^2}{\log(n\log n)}\right) = \Theta\left(\frac{n^2 (\log n)^2}{\log n}\right) = \Theta(n^2 \log n)
π ( U ) − π ( L ) ≈ ln U U − ln L L ≈ ln L L = Θ ( log ( n log n ) ( n log n ) 2 ) = Θ ( log n n 2 ( log n ) 2 ) = Θ ( n 2 log n )
错误源 1 的概率 :对于某个非零系数 c k c_k c k ,它至多有 O ( n log n ) O(n\log n) O ( n log n ) 个素因子。在 [ L , U ] [L, U] [ L , U ] 内约有 Θ ( n 2 log n ) \Theta(n^2 \log n) Θ ( n 2 log n ) 个素数中,p p p 恰好整除 c k c_k c k 的概率:
Pr [ 错误源 1 ] ⩽ O ( n log n ) Θ ( n 2 log n ) = O ( 1 n ) \Pr[\text{错误源 1}] \le \frac{O(n \log n)}{\Theta(n^2 \log n)} = O\left(\frac{1}{n}\right)
Pr [ 错误源 1 ] ⩽ Θ ( n 2 log n ) O ( n log n ) = O ( n 1 )
错误源 2 的概率 :由 Schwartz-Zippel 引理,随机 r ∈ Z p r \in \mathbb{Z}_p r ∈ Z p 使得非零多项式 g ( x ) m o d p g(x) \bmod p g ( x ) mod p 取值为零的概率至多为 n / p ⩽ n / L n/p \le n/L n / p ⩽ n / L :
Pr [ 错误源 2 ] ⩽ n ( n log n ) 2 / 2 = 2 n ( log n ) 2 = O ( 1 n ) \Pr[\text{错误源 2}] \le \frac{n}{(n\log n)^2 / 2} = \frac{2}{n(\log n)^2} = O\left(\frac{1}{n}\right)
Pr [ 错误源 2 ] ⩽ ( n log n ) 2 /2 n = n ( log n ) 2 2 = O ( n 1 )
由联合界,总错误概率为 O ( 1 / n ) O(1/n) O ( 1/ n ) 。
复杂度与数据流适用性
指标
复杂度
时间
O ( n ) O(n) O ( n ) ——遍历所有元素,逐步累乘 ( r − a i ) m o d p (r - a_i) \bmod p ( r − a i ) mod p
空间
O ( log n ) O(\log n) O ( log n ) ——只需存储当前部分积、r r r 和 p p p
错误
O ( 1 / n ) O(1/n) O ( 1/ n ) (单边错误,仅假阳性)
Lipton 算法的一个重要优势是天然适合数据流模型 (Data Stream Model):元素 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a 1 , a 2 , … , a n 逐个到达,算法只需维护当前部分积 ∏ i = 1 k ( r − a i ) m o d p \prod_{i=1}^{k}(r - a_i) \bmod p ∏ i = 1 k ( r − a i ) mod p ,每到达一个新元素只需一次乘法和一次取模。这在处理大规模数据时尤为有用——数据可能太大而无法全部存储在内存中。
推广:一般多重集相等性
Lipton 算法不局限于元素唯一性,可以推广到一般的多重集相等性检验:给定两个多重集 A = ( a 1 , … , a n ) A = (a_1, \ldots, a_n) A = ( a 1 , … , a n ) 和 B = ( b 1 , … , b n ) B = (b_1, \ldots, b_n) B = ( b 1 , … , b n ) ,判断 A = B A = B A = B 。只需分别计算 FING ( A ) = ∏ ( r − a i ) m o d p \text{FING}(A) = \prod(r - a_i) \bmod p FING ( A ) = ∏ ( r − a i ) mod p 和 FING ( B ) = ∏ ( r − b i ) m o d p \text{FING}(B) = \prod(r - b_i) \bmod p FING ( B ) = ∏ ( r − b i ) mod p ,然后比较即可。分析完全类似。
Fingerprinting 的统一视角
回顾本讲的所有算法,它们共享一个统一的范式:
问题
对象
指纹 FING \text{FING} FING
随机源
时间
PIT
多项式 Q Q Q
Q ( r 1 , … , r n ) Q(r_1, \ldots, r_n) Q ( r 1 , … , r n )
随机取值点
取决于电路
字符串相等(公共随机)
a ∈ { 0 , 1 } n a \in \{0,1\}^n a ∈ { 0 , 1 } n
∑ a i r i m o d p \sum a_i r^i \bmod p ∑ a i r i mod p
随机 r ∈ Z p r \in \mathbb{Z}_p r ∈ Z p
O ( n ) O(n) O ( n )
字符串相等(私有随机)
a ∈ { 0 , 1 } n a \in \{0,1\}^n a ∈ { 0 , 1 } n
a m o d p a \bmod p a mod p
随机素数 p p p
O ( n ) O(n) O ( n )
二部图匹配
Edmonds 矩阵 M \bm{M} M
det ( M ) ∥ x i j = r i j \det(\bm{M})\big\|_{x_{ij}=r_{ij}} det ( M ) x ij = r ij
随机赋值
O ( n ω ) O(n^\omega) O ( n ω )
矩阵乘法验证
矩阵 D \bm{D} D
D r \bm{D}\bm{r} D r
随机向量 r \bm{r} r
O ( n 2 ) O(n^2) O ( n 2 )
字符串匹配
子串 T j T_j T j
T ˉ j m o d p \bar{T}_j \bmod p T ˉ j mod p
随机素数 p p p
O ( n ) O(n) O ( n )
多重集相等
多项式 f A f_A f A
f A ( r ) m o d p f_A(r) \bmod p f A ( r ) mod p
随机 r r r 和 p p p
O ( n ) O(n) O ( n )
Fingerprinting 的本质是一种「降维」策略 :将高维或大规模的对象映射到低维空间中,利用随机性保证「保距性」——不同对象大概率映射为不同指纹。错误分析的核心工具是两个:
Schwartz-Zippel 引理 :非零多项式在随机点处为零的概率有上界
素数定理 :控制随机素数整除特定整数的概率
这一思想不仅是随机算法的基石,也是后续课程中哈希技术、数据流算法、降维方法(如 Johnson-Lindenstrauss 引理)的核心起点。