绪论
- 引言
1
当一个算法面临某种选择事,有时随机选择比耗时做最优选择更好,尤其是当最优选择时间大于随机选择的平均时间。概率算法只能是期望的时间更有效,但有可能遭受到最坏的可能性。
2
2.1 平均时间:确定算法中,输入一定等概率出现的输入实例的执行平均时间
2.2 期望时间:概率算法中,反复解同一个输入实例所花的平均执行时间
平均的期望时间:所有输入实例上平均的期望执行时间
最坏的期望时间:最坏的输入实例上的期望执行时间
3 特点
不可再现性
分析困难
- 概率算法的分类
1 基本特征
随机决策:同一实例上执行时间和结果都可能不同
2 分类
Numerical、Monte Carlo、Las Vegas、Sherwood
2.1 数字算法:例如求一个系统中队列的平均长度,概率算法求得答案是近似的,算法执行时间越长精度越高
2.2 MC算法:问题只有一个正确的解,无近似解,例如判定问题(只能有正确或者错误)
特点:总能给出一个答案,确未必正确,正确的概率和执行时间成正比
2.3 LV算法:算法绝不返回错误的答案,但有时返回不了答案,成功的概率和执行时间成正比
2.4 Sherwood算法:总能给出正确答案,当某些确定算法解决一个特殊问题平均时间比最坏时间快得多时,我们可以用sherwood算法来减少,甚至是消除好的和坏的实例之间的差别
数值概率算法
- π \pi π值计算:面积法
Darts(n):
k = 0
for i in (0, n):
x = uniform(0,1)
y = uniform(0,1) #这里若改成y=x,则算法估算的结果应该是圆内切正方形的边长
if x^2 +y^2 < 1:
k++
return 4k/n
- 数字积分:仍然是面积法
Monte Carlo积分(非Monte Carlo算法)
计算定积分的值:
2.1 概率算法1
相当于面积法
HitorMiss(f, n)
k = 0
for i in (0, n):
x = uniform(0,1)
y = uniform(0,1)
if y < f(x):
k++
return k/n
2.2 概率算法2
在积分区间内均匀产生点,求点上函数值得算数平均值,再乘以区间宽度
Crude(f,a,b,n):
s = 0
for i in (0, n):
x = uniform(a, b)
s += f(x)
return s*(b-a)/n
给定n下,Crude算法的方差不会大于HitorMIss,但可能需要计算f(x),耗时更多
2.3 确定的算法
梯形算法:将区间分为n-1个子区间,每个区间长度为d
Trapezoid(f,n,a,b):
s = 0
d = (b - a) / (n -1)
for i in (1, n):
s+=[f(a+i*d)+f(a+i*d+d)]*d/2
return s
梯形算法的精度在相同迭代次数下较高,但是有如下缺点
a)有时求不出解
b)多重积分极速增加算法复杂度,但是概率算法对维度不敏感
- 概率计数
例1:25个人生日存在相同的概率
从n个对象中选择两两不同的k个有 n ! ( n − k ) ! \frac {n!} {(n-k)!} (n−k)!n!种
从n个对象中选择k个可重复的有 n k n^k nk种
因此不同的概率为 n ! ( n − k ) ! n k \frac {n!} {(n-k)!n^k} (n−k)!nkn!
近似地有, n ! ( n − k ) ! n k = e − k 2 / 2 n \frac {n!} {(n-k)!n^k} = e^{-k^2/2n} (n−k)!nkn!=e−k2/2n
例2:求集合X的势
X势具有n个元素的集合,又放回地随机均匀独立地从X中选取元素,k是第一次重复之前选出的元素数目,则当n足够大时,k的期望值趋近于
n
π
/
2
\sqrt{n \pi /2}
nπ/2
例3:多重集合中不同对象数目的估计
N是磁带上总词数,n是其中不同词的数目。
方法一:排序
方法二:散列表
方法三:将N个单词随机散列到m长度的位串上,
m
=
5
+
l
g
M
m = 5 + lgM
m=5+lgM
pi(x, y):
return x中出现的首位y的位置
WordCount():
y[1...m+1] = 0
for word in sentence:
y[pi(h(word), 1)] = 1
return pi(y,0)
后续一系列证明,证明计数结果的上界约为
2
k
2^k
2k,下界约为
2
k
−
2
2^{k-2}
2k−2,约等于
2
k
/
1.5
2^k/1.5
2k/1.5
原证明过程大致为举例m=4时,若返回值为4时(前3位均为1,第四位出现0)的概率为35.6%,因此概率不大…
因此这是一个特殊情况的概率举例,的确若存在16个不同的单词,所有单词的最高位均没有填到第四位的概率为
(
15
/
16
)
1
6
(15/16)^16
(15/16)16。
若我们扩大m的值,返回值为5,则上界为32,因为所有单词均没有填到第五位的概率为
(
31
/
32
)
3
2
)
(31/32)^32)
(31/32)32),应该更小。
那么对于下界,则对于4个单词,至少有一个填到第三位(001)的概率为
1
−
(
7
/
8
)
4
=
41.4
1-(7/8)^4=41.4%
1−(7/8)4=41.4,因此概率足够…
略感觉这里对于概率的要求有些随性,不很严谨。
Sherwood算法
算法的根本目的在于平滑不同输入实例的执行时间
A:确定性算法,可能会存在一个数据执行时间远大于平均时间
B:概率算法,
t
B
(
x
)
≈
t
ˉ
A
(
n
)
+
s
(
n
)
t_B(x) \approx \bar t_A(n)+s(n)
tB(x)≈tˉA(n)+s(n),
s
(
n
)
s(n)
s(n)是为了均匀性付出的成本
虽然B执行时间也可能存在大于B算法平均值的情况,但是这不再与实例有关。因此,不再有最坏情况的实例,但有最坏的执行时间。
我理解此类算法的根本意义在于通过随机变换输入实例,使得最坏实例都有可能变好,这样使得不存在某个实例一定不好。
- 选择与排序
1.1 在n个元素中选择第k个最小元素的算法,有两种方法…(均为确定性算法此处略过)
确定性算法的时间依赖于元素之间的相对顺序
1.2 概率算法:随机选择T中的元素作为划分元
注意:
算法的某次执行有可能达到 O ( n 2 ) O(n^2) O(n2),但可能性和实例无关。(注意理解这句话,若不是概率算法,那么实例对应的执行时间是固定的,若添加了概率,则对应之前最坏情况的实例可能执行时间不再是最坏的情况,但所有实例都有可能选到最坏情况的执行时间)
将选择和排序的确定算法修改为Sherwood算法很简单,但若其他复杂算法可能会很难修改,此外,只有当算法平均时间较优,最坏性较差,才有修改的价值
- 处理步骤
①预处理:将被解的实例变换到一个随机实例
f : X → Y f:X \to Y f:X→Y是问题函数
X n X_n Xn是大小为n的实例
A n A_n An是大小为n的集合,并可以有效均匀随机抽样
随机预处理过程:
u : X × A → X u:X \times A \to X u:X×A→X,X可随机抽样变换为另一个实例,存在且只存在一个
v : A × Y → Y v:A \times Y \to Y v:A×Y→Y,y的解可变换为原实例y的解
且u和v在最坏情况下仍能够有效计算
②用确定算法解此随机实例,得到一个解
③后处理:将此解变换为对原实例的解。
RH(x):
n = size(X)
r = uniform(An)
y = u(x, r)
s = f(y)
return v(r, s)
例1 选择和排序:将输入实例打乱(相当于洗牌)
例2 离散对数计算
定义
a
=
g
x
m
o
d
p
a = g^x \mod p
a=gxmodp,记
x
=
log
g
,
p
a
x = \log_{g, p} a
x=logg,pa
首先明确对于不同的x,a是一个周期循环的数,例如
因此我们计算x的值,只需要依次循环遍历即可。(需要注意可能存在无解的情况)
dlog(g,a,p):
x = 0, y = 1
do{
x++
y*=g
}while(y % p != a and x != p)
return x #当无解时返回p
那么这就有了问题:当输入a为11时,注定需要循环18次才能找到i的值。
因此我们可以通过随机预处理改变输入实例a的值,再通过后处理还原。
这里需要两条定理:
①
log
g
,
p
(
s
t
m
o
d
p
)
=
(
log
g
,
p
s
+
log
g
,
p
t
)
m
o
d
(
p
−
1
)
\log_{g,p} (st \mod p) = (\log_{g,p} s + \log_{g,p} t) \mod (p-1)
logg,p(stmodp)=(logg,ps+logg,pt)mod(p−1)
②
log
g
,
p
(
g
r
m
o
d
p
)
=
r
f
o
r
0
≤
r
≤
p
−
2
\log_{g,p} (g^r \mod p) = r for 0 \le r \le p-2
logg,p(grmodp)=rfor0≤r≤p−2
(注意上述两条定理不满足当r=p-1的情况)
这里就可以用一个随机的r将原本的输入实例a向右移动若干位,使得最坏实例下执行时间变短
dlogRH(g,a,p):
r = uniform(0, p-2)
b = ModularExponent(g,r,p)#也就是求g^r%p
return (ModularLog(g,p,ab % p) - r) %(p-1)
这样一种随机预处理就提供了一种加密计算的方法,因为u的分布时独立于x的分布,除了泄露size带下外,没有任何其他信息的泄露
- 搜索有序表
3.1 有序表构成:通过两个数组来定义这个有序的静态链表
3.2 搜索方法
折半查找:对于val说有序的表可用
顺序查找:链式结构表,最坏时间为O(n)
Search(x,i):
while x > val[i]:
i = ptr[i]
return i
A(x):
return Search(x, head)
显然平均时间为 n + 1 2 \frac {n+1} 2 2n+1
对应的概率算法:
D(x):
i = uniform(0, n)
case:
x == val[i]: return i
x > val[i]: return Search(x, i)
x < val[i]: return Search(x, head)
这里计算平均时间:i为随机初始位置,j为实际位置
i<j时,时间为
j
−
i
j-i
j−i,
i>j时,时间为
j
j
j,
平均时间为
∑
i
=
0
n
(
∑
j
=
0
i
−
1
j
+
∑
j
=
i
n
(
j
−
i
)
)
=
n
3
−
1
3
n
\sum_{i=0}^n(\sum_{j=0}^{i-1}j+\sum_{j=i}^{n}(j-i))=\frac n 3 - \frac 1 {3n}
∑i=0n(∑j=0i−1j+∑j=in(j−i))=3n−3n1
可以见得概率算法的平均时间更少
我们寻求一个确定性算法,平均时间为
O
(
n
)
O(\sqrt n)
O(n)
首先我们在n个数中选择前l个数,因为数组的随机性,我们相当于将有序空间分为l个区间,每个区间随机选择一个数,其中与x在同一区间的数为y。
若y<x,从y再寻找到x只需要不超过n/l时间
若y>x,则需要从前一个区间的随机数出发寻找x,平均距离为n/l
综上,平均的时间为
(
n
l
+
l
)
/
2
(\frac n l+l)/2
(ln+l)/2,显然当
l
=
n
l=\sqrt n
l=n时,时间最少,为
n
\sqrt n
n
B(x):
i = head
max = val[i]
for j in (0, sqrt(n)):
if max<y<=x:
i = j
max = val[j]
return Search(x,i)
# 寻找的是比x小的最大值对应的下标
Las Vegas算法
-
比较
Sherwood一般平均性能较差,可以计算执行上界,一定能够找到解
Las Vegas算法可以获得更有效率的算法,时间上界可能不存在,可能会冒着找不到解的风险,但同一实例同一算法有独立的集会求解 -
算法表示 LV(x,y success)
p(x):成功率
s(x):算法成功时的期望时间
e(x):算法失败时的期望时间
t(x):算法找到一个正确解的期望时间
有关系:t=p*s+(1-p)(e+t),解得t=s+(1-p)e/p -
Las Vegas方法求解n皇后
QueensLv(success):
col, diag45, diag135 = {}
k = 0 #从第k行开始
repeat:
nb = 0
for j in range(8):
if Not(j in col or j - (k + 1) in diag45 or j + (k + 1) in diag135):
nb++
if uniform(0,nb) == 0: #这种概率方法还较为巧妙,可以控制均匀概率
i = j
if nb > 0:
k++;
try[k] = i
col.append(i)
diag45.append(i-k)
diag45.append(i+k)
until nb == 0 or k == 8 # 找不到合适的位置,或者try数组填满
success = nb > 0
上面这种方法下,每次具有一定失败的概率,但即使是考虑失败的次数,经过多次实验结果,直到第一次成功搜索的平均结点数也大大优于回溯法。
问题:LV算法一旦失败就必须从头再来
因此我们可以先随机放置若干个皇后,然后再用回溯法放置后若干个结点,不再考虑前面随机放置的结点。
- 模p平方根
定义: x ≡ y 2 m o d p x \equiv y^2 \mod p x≡y2modp,其中p是一个奇素数, x ∈ [ 1 , p − 1 ] x \in [1,p-1] x∈[1,p−1]
1)x为模p的二次剩余
2)若 y ∈ [ 1 , p − 1 ] y \in [1,p-1] y∈[1,p−1],则y为x模p的平方根
定理1:任何一个模p的二次剩余至少有两个不同的平方根
显然对于 ( p − y ) 2 = p 2 − 2 p y + y 2 = > ( p − y ) 2 m o d p = y 2 m o d p (p-y)^2=p^2-2py+y^2 => (p-y)^2 \mod p=y^2 \mod p (p−y)2=p2−2py+y2=>(p−y)2modp=y2modp,且由于p是奇素数, y ≠ p − y y \not =p-y y=p−y
定理2:任何一个模p的二次剩余至多有两个不同的平方根
由定理1知至少存在 a 2 ≡ b 2 m o d p a^2 \equiv b^2 \mod p a2≡b2modp,则有 a 2 = p m + r , b 2 = p n + r a^2=pm+r, b^2=pn+r a2=pm+r,b2=pn+r,故 a 2 − b 2 ≡ 0 m o d p , a 2 − b 2 = p ( m − n ) = ( a + b ) ( a − b ) a^2-b^2 \equiv 0 \mod p, a^2-b^2=p(m-n)=(a+b)(a-b) a2−b2≡0modp,a2−b2=p(m−n)=(a+b)(a−b),其中 a − b < p a-b<p a−b<p,则必有 a + b ≡ 0 m o d p a+b \equiv 0 \mod p a+b≡0modp,又因为a和b之间差不超过p,且a、b本身不超过p,故只能有 a + b = p a+b=p a+b=p,得到 a = p − b a=p-b a=p−b。因此对于任意两个不同的平方根,均只有b和p-b两种不同的形式
定理3:1到p-1之间的整数恰有一半是模p的二次剩余
由定理1、2知道,对于任何一个模p的二次剩余都只有两个不同的平方根,因此对于[1,p-1]内的y对应的 y 2 y^2%p y2有两两相同,又因为二次剩余的平方根最多只有两个,所以不可能有重复的两对 y 2 y^2%p y2是相同的,故而正好有 ( p − 1 ) / 2 (p-1)/2 (p−1)/2个模p的二次剩余。
定理4:对于 ∀ x ∈ [ 1 , p − 1 ] \forall x \in [1,p-1] ∀x∈[1,p−1],p是任一奇素数,则有 x ( p − 1 ) / 2 ≡ ± 1 m o d p x^{(p-1)/2} \equiv \pm 1 \mod p x(p−1)/2≡±1modp,且x是模p的二次剩余当且仅当 x ( p − 1 ) / 2 ≡ 1 m o d p x^{(p-1)/2} \equiv 1 \mod p x(p−1)/2≡1modp
这里证明需要通过费马小定理: p p p为质数, a a a为任意自然数,都有 a p ≡ a m o d p a^p \equiv a \mod p ap≡amodp
费马小定理的证明可以通过数学归纳法,证明 ( a + 1 ) p m o d p = a (a+1)^p \mod p = a (a+1)pmodp=a其中需要用到 ( p k ) \dbinom p k (kp)可以被p整除(因为p是素数)
在费马小定理的基础上,我们得到 a p − 1 ≡ 1 m o d p a^{p-1} \equiv 1 \mod p ap−1≡1modp,因此有 p ∣ ( a ( p − 1 ) / 2 − 1 ) ∗ ( a ( p − 1 ) / 2 + 1 ) p | (a^{(p-1)/2}-1)*(a^{(p-1)/2}+1) p∣(a(p−1)/2−1)∗(a(p−1)/2+1)那么需要满足 p ∣ ( a ( p − 1 ) / 2 − 1 ) p|(a^{(p-1)/2}-1) p∣(a(p−1)/2−1)或者 p ∣ ( a ( p − 1 ) / 2 + 1 ) p|(a^{(p-1)/2}+1) p∣(a(p−1)/2+1),进而得到 a ( p − 1 ) / 2 ≡ ± 1 m o d p a^{(p-1)/2} \equiv \pm 1 \mod p a(p−1)/2≡±1modp
最后一个二次剩余不会证明。。。。。
因此想要判定x是否为模p的二次剩余,只需要计算 x ( p − 1 ) / 2 m o d p x^{(p-1)/2} \mod p x(p−1)/2modp是否为1即可(但是这里p需要是奇素数吧)
问题:已知p是奇素数,x是模p的二次剩余,如何计算x模p的平方根?
首先由前面定理可知,平方根有且仅有两个;
若p=4n+3,这时候很容易得到 x ( p − 1 ) / 2 m o d p = 1 = > x ( p + 1 ) / 2 m o d p = x x^{(p-1)/2} \mod p =1 => x^{(p+1)/2} \mod p =x x(p−1)/2modp=1=>x(p+1)/2modp=x,显然可以得到x模p的平方根为 x ( p + 1 ) / 4 x^{(p+1)/4} x(p+1)/4
但若p=4n+1时,没有有效的确定性算法,只能借助于Las Vegas算法
Las Vegas算法
这部分PPT介绍的不够清晰,主要是介绍顺序不太好吧。
首先我们明确要计算x模p的平方根,例如计算x=7,p=53时的平方根
因为由定理4我们知道 x ( p − 1 ) / 2 ≡ + 1 m o d p x^{(p-1)/2} \equiv + 1 \mod p x(p−1)/2≡+1modp
(以下的 x \sqrt x x均为带模运算的平方根)
因此我们可以通过计算 ( a + x ) ( p − 1 ) / 2 m o d p (a+\sqrt x)^{(p-1)/2} \mod p (a+x)(p−1)/2modp和 ( a − x ) ( p − 1 ) / 2 m o d p (a-\sqrt x)^{(p-1)/2} \mod p (a−x)(p−1)/2modp的结果,这种情况下只能为±1。若我们能寻找到一对恰好为1和-1,则有
( a + x ) ( p − 1 ) / 2 m o d p = ( c + d x ) m o d p = 1 (a+\sqrt x)^{(p-1)/2} \mod p = (c+d \sqrt x) \mod p = 1 (a+x)(p−1)/2modp=(c+dx)modp=1
( a − x ) ( p − 1 ) / 2 m o d p = ( c − d x ) m o d p = − 1 (a-\sqrt x)^{(p-1)/2} \mod p = (c-d \sqrt x) \mod p = -1 (a−x)(p−1)/2modp=(c−dx)modp=−1(这里ppt也没有说明证明原理,可能跟复数运算的性质有关)
我们将两个式子分别相加减,得到 d x ≡ 1 m o d p d\sqrt x \equiv 1 \mod p dx≡1modp,并且 c ≡ 0 m o d p c \equiv 0 \mod p c≡0modp
因此,我们每次只需要计算 ( a + x ) ( p − 1 ) / 2 m o d p (a+\sqrt x)^{(p-1)/2} \mod p (a+x)(p−1)/2modp,若c为0,d不为0,则最终必然是±1;若c不为0,d为0,则说明两个取模是同号。
之后我们将问题转换为求d的逆元。
求逆元需要用到拓展的欧几里得定理,也就是辗转相除法的逆过程
例如,求p=53时,41的逆元。
这里可以看作时求41和53的最大公因数,我们知道和质数的最大公因数一定是1,则有辗转相除法的过程:
53 = 41 ∗ 1 + 12 53=41*1+12 53=41∗1+12
41 = 12 ∗ 3 + 5 41=12*3+5 41=12∗3+5
12 = 5 ∗ 2 + 2 12=5*2+2 12=5∗2+2
5 = 2 ∗ 2 + 1 5=2*2+1 5=2∗2+1
2 = 2 ∗ 1 + 0 2=2*1+0 2=2∗1+0
我们逆推这个公式有:
1 = 5 − 2 ∗ 2 = 5 − ( 12 − 5 ∗ 2 ) ∗ 2 = 5 ∗ 5 − 12 ∗ 2 = ( 41 − 12 ∗ 3 ) ∗ 5 − 12 ∗ 2 = 41 ∗ 5 − 12 ∗ 17 = 41 ∗ 5 − ( 53 − 41 ∗ 1 ) ∗ 17 = − 53 ∗ 17 + 22 ∗ 41 1=5-2*2=5-(12-5*2)*2=5*5-12*2=(41-12*3)*5-12*2=41*5-12*17=41*5-(53-41*1)*17=-53*17+22*41 1=5−2∗2=5−(12−5∗2)∗2=5∗5−12∗2=(41−12∗3)∗5−12∗2=41∗5−12∗17=41∗5−(53−41∗1)∗17=−53∗17+22∗41
因此我们可以得到22为41模53的逆元,则另一个逆元为53-22=31
rootLV(x,p,y,success):
a = uniform(1,p-1)
if a^2%p == x:
success = true
y = a
else:
计算c,d
if d == 0:
success = false
else # 当d不为0时,c == 0
计算y为d的逆元
success = true
- 整数的因数分解
n是一个合数,寻找非平凡解有两个过程:
prime(n):判断n是否为素数(Monte Carlo)
split(n):知道n的一个非平凡因数
- 朴素的split算法
split(n):
for i in (2,sqrt(n)):
if n % i == 0:
return i
return 1
- 合数的二次剩余
定义:若x和n互质,且存在 y ∈ [ 1 , n − 1 ] y \in [1,n-1] y∈[1,n−1],使得 x ≡ y 2 m o d n x \equiv y^2 \mod n x≡y2modn,则x为模n的二次剩余
对于素数p,模p的二次剩余一定有两个不同平方根,但是对于合数n则未必,例如 8 2 ≡ 1 3 2 ≡ 2 2 2 ≡ 2 7 2 m o d 35 8^2\equiv 13^2 \equiv 22^2 \equiv 27^2 \mod 35 82≡132≡222≡272mod35,且我们发现两两相加为n
定理:若n=qp,qp是互不相同的素数,则模n的二次剩余恰有4个平方根
Dixon因数分解算法
基本思想,找两个与n互素的整数a和b,使得 a 2 ≡ b 2 m o d n a^2\equiv b^2 \mod n a2≡b2modn,因为有 a 2 − b 2 ≡ ( a + b ) ( a − b ) ≡ 0 m o d n a^2-b^2\equiv (a+b)(a-b) \equiv 0 \mod n a2−b2≡(a+b)(a−b)≡0modn,若n既不能整除a+b,也不能整除a-b,则可以有n的一个平凡因子满足 x ∣ ( a + b ) , n x ∣ ( a − b ) x| (a+b), \frac n x|(a-b) x∣(a+b),xn∣(a−b),故n和a+b的最大公因子是n的一个非平凡解
Dixon(n,x,success):
if n % 2 == 0:
success = true
x = 2
else:
for i in range(2,log3n): #log3暂时不知是为啥
if n^(1/i) 是整数:
x = n^(1/i)
success = true
寻找a,b使得a^2 % n = b^2 % n
if a=±b (mod n):
success = false
else:
x = gcd(a+b, n)
success = true
接下来就是如何找到a和b的问题
首先定义k平滑:若一个整数x的所有素因子均在前k个素数中,则称x是k平滑的
例如35=5*7,则35不是1,2,3平滑的,但是4,5,6…平滑的
(目的:k平滑的因子可以通过split算法找到)
Step1:
重复下面两个步骤:
1)随机在1-n-1中找到一个数,若正好是因子,直接结束
2)否则设 y = x 2 m o d n y=x^2\mod n y=x2modn,若y是k平滑,则将x和y的因数分解保存在表里
直到表里填够k+1行数据
(为什么要k+1行?确保一个k+1行中有几行的因数分解相乘后指数均为偶数)
(为什么需要偶数?因为要确保相乘后的值可以开根号?)
(为什么需要开根号?因为这样就可以得到不同的a和b确有相同的模剩余)
Step2:
在k+1个等式中寻找若干个等式使得相应的因数分解的积中前k个素数的指数均为偶数
证明:对于k+1×k的矩阵,必有线性相关的行,则我们将指数为偶数记1,奇数记0,很容易得到这样一个线性相关的矩阵,我们只需要找到这些行对应的等式即可
Step3:
令a为找到的若干个等式x的乘积
令b为找到的若干个等式y的乘积(指数均为偶数)开平方
若 a ≡ b m o d n a\equiv b \mod n a≡bmodn则失败,否则找到
如何选择k的值:
设 L = e l n n l n l n n L=e^ {\sqrt {lnnlnlnn}} L=elnnlnlnn,通常 k = L k=\sqrt L k=L,期望时间 O ( L 2 ) O(L^2) O(L2)
Monte Carlo算法
该算法对任和实例均能以高概率找到正确解,但算法出错时,没有警告信息
-
基本概念
Def1:MC算法以不小于p的概率反会正确的解,则成为p-正确,算法优势是p-1/2
Def2:MC可以对同一实例决不给出两个不同的正确解,则称该算法是相容的/一致的 -
基本思想
为了增加一个一致的、p-正确算法成功的概率,只需多次调用同一算法,然后选择出现次数最多的解
例如:MC(x)是一个一致、75%-correct的MC算法,考虑
MC3(x):
t = MC(x)
u = MC(x)
v = MC(x)
if t == u or t == v:
return t
return v
证明:
1)若t,u,v均正确,一定正确,概率为 ( 3 / 4 ) 3 (3/4)^3 (3/4)3
2)若t,u或者t,v或者u,v正确,最终也正确,概率为 3 ∗ ( 3 / 4 ) 2 ∗ ( 1 / 4 ) 3*(3/4)^2*(1/4) 3∗(3/4)2∗(1/4)
3)若只有一个正确,则只有v正确,才会返回正确答案,概率为 ( 3 / 4 ) ∗ ( 1 / 4 ) 2 (3/4)*(1/4)^2 (3/4)∗(1/4)2
总概率约为85%
- 定理:MC是一个一致的、 ( 0.5 + σ ) (0.5+\sigma) (0.5+σ)-correct的MC算法,x是一个被解实例,若调用MC(x)至少 − 2 lg 1 − 4 ∗ σ 2 l g ( 1 / ϵ ) -\frac 2 {\lg {1-4*\sigma^2}} lg(1/ \epsilon) −lg1−4∗σ22lg(1/ϵ),并返回出现频数最高的解,则可以得到一个解同样实例的一致的 ( 1 − ϵ ) (1-\epsilon) (1−ϵ)-correct的MC算法(其中 σ + ϵ < 0.5 \sigma+\epsilon <0.5 σ+ϵ<0.5)
证明:设 n ≥ − 2 lg 1 − 4 σ 2 lg ( 1 / ϵ ) n\ge -\frac 2 {\lg {1-4\sigma^2}} \lg (1/ \epsilon) n≥−lg1−4σ22lg(1/ϵ)为调用次数, m = ⌊ n / 2 ⌋ + 1 m = ⌊ n/2⌋+1 m=⌊n/2⌋+1,显然当正确解数量大于等于m时,能够返回正确值;反之,则会返回错误解。因此出错概率为 ∑ i = 0 m − 1 ( n i ) ( σ + 0.5 ) i ( 0.5 − σ ) n − i = ∑ i = 0 m − 1 ( n i ) ( σ + 0.5 ) n / 2 ( 0.5 − σ ) n / 2 ( σ + 0.5 ) i − n / 2 ( 0.5 − σ ) n / 2 − i ≤ ∑ i = 0 n ( n i ) ( 0.25 − σ 2 ) n / 2 = 2 n ( 0.25 − σ 2 ) n / 2 = ( 1 − 4 σ 2 ) n / 2 ≤ ( 1 − 4 σ 2 ) l g ϵ l g 1 − 4 σ 2 = ( 1 − 4 σ 2 ) l o g 1 − 4 σ 2 ϵ = ϵ \sum_{i=0}^{m-1} \binom n i (\sigma +0.5)^i(0.5 - \sigma)^{n-i}=\sum_{i=0}^{m-1} \binom n i (\sigma +0.5)^{n/2}(0.5 - \sigma)^{n/2}(\sigma +0.5)^{i-n/2}(0.5 - \sigma)^{n/2-i}\le\sum_{i=0}^{n} \binom n i (0.25 - \sigma^2)^{n/2}=2^n(0.25-\sigma^2)^{n/2}=(1-4\sigma^2)^{n/2}\le(1-4\sigma^2)^{\frac {lg \epsilon} {lg 1-4\sigma^2}}=(1-4\sigma^2)^{log_{1-4\sigma^2}^{\epsilon}}=\epsilon ∑i=0m−1(in)(σ+0.5)i(0.5−σ)n−i=∑i=0m−1(in)(σ+0.5)n/2(0.5−σ)n/2(σ+0.5)i−n/2(0.5−σ)n/2−i≤∑i=0n(in)(0.25−σ2)n/2=2n(0.25−σ2)n/2=(1−4σ2)n/2≤(1−4σ2)lg1−4σ2lgϵ=(1−4σ2)log1−4σ2ϵ=ϵ。
- 有偏算法
Def:
偏真算法:MC(x)是解某个判定问题,返回true时总是正确的,返回false才有可能产生错误的解,则称此算法是偏真的。
偏 y 0 y_0 y0算法:当 y 0 y_0 y0是某个特定解,若存在问题实例的子集X使得
1)若被解实例 x ∉ X x\not \in X x∈X,则算法MC(x)返回的解总是正确的(无论是 y 0 y_0 y0还是非 y 0 y_0 y0)
2)若 ∀ x ∈ X \forall x \in X ∀x∈X,MC并非对所有实例都返回正确解,正确解就是 y 0 y_0 y0
显然在这种情况下,返回 y 0 y_0 y0总是正确的,返回非 y 0 y_0 y0以p概率正确
我们重复调用k次MC(x),得到结果 y 1 , y 2 , y 3 . . . . . . y k y_1,y_2,y_3......y_k y1,y2,y3......yk,则
若存在某个解 y i = y 0 y_i=y_0 yi=y0,则是一个正确解
若均不等于 y 0 y_0 y0,则y_0仍有可能是正确解(当 x ∈ X x\in X x∈X),这种情况的错误概率为 ( 1 − p ) k (1-p)^k (1−p)k
得到结论,重复调用一个一致的,p-正确的,偏 y 0 y_0 y0的MC算法k次,可以得到一个 ( 1 − ( 1 − p ) k ) (1-(1-p)^k) (1−(1−p)k)正确的算法
- 主元素问题
Def:数组T中存在一个元素x个数大于n/2,n为数组大小时,则x为数组T的主元素
maj(T):
i = uniform(0,n)
x = T[i]
k = 0
for j in range(0,n):
if T[j] == x:
k++
return k > n/2
显然该算法是一个偏真的1/2正确的算法
若返回true,则一定存在主元素,且选中主元素的概率大于1/2
若返回false,则可能没有主元素
若我们重复调用该算法,可以降低错误概率
设重复次数为k,显然错误概率降低为
(
1
−
p
)
k
(1-p)^k
(1−p)k
则我们想要错误率小于
ϵ
\epsilon
ϵ时,可以得到
k
=
l
o
g
1
−
p
ϵ
k = log_{1-p}^{\epsilon}
k=log1−pϵ
majMC(T,e):
k = log(1-p,e)
for i in (1,k):
if maj(T):
return true
return false
- 素数测定
6.1 简单的概率算法
prime(n):
d = uniform(2,sqrt(n))
return (n mod d)!=0
显然是个偏假的算法,并且效果很差
6.2 Femat小定理
若n是素数,则
∀
a
∈
[
1
,
n
−
1
]
\forall a \in [1,n-1]
∀a∈[1,n−1],有
a
n
−
1
m
o
d
n
=
1
a^{n-1}mod n =1
an−1modn=1
逆否命题则为若
a
n
−
1
m
o
d
n
!
=
1
a^{n-1}mod n !=1
an−1modn!=1,则n不是素数
Fermat(n){
a = uniform(1...n)
return a^(n-1) mod n == 1
}
仍然是一个偏假的算法
6.3 伪素数
定义:满足
a
n
−
1
m
o
d
n
=
1
a^{n-1}mod n =1
an−1modn=1的合数n被称为以a为底的伪素数,a称为n的伪证据
其中伪素数+素数称为拟素数,也就是符合费马小定理的数
但是因为对于不同的合数,他们的伪证据数量不一定,有的甚至可以找到99%比自己小的数都是伪证据。因此对于Fermat算法我们不能确定它是p-正确的。
6.4 强伪素数
对于n-1分解为
2
s
∗
t
2^s*t
2s∗t,其中t为奇数。对于
1
<
a
<
n
−
1
1<a<n-1
1<a<n−1,B(n)满足下面两个条件之一:
①
a
t
m
o
d
n
=
1
a^t \mod n = 1
atmodn=1
②存在
i
∈
[
0
,
s
]
i \in [0,s]
i∈[0,s]使得
a
2
i
t
m
o
d
n
=
−
1
a^{2^it} \mod n = -1
a2itmodn=−1
则n为素数时,一定满足
∀
a
∈
[
2
,
n
−
2
]
\forall a \in [2,n-2]
∀a∈[2,n−2],均有
a
∈
B
(
n
)
a\in B(n)
a∈B(n)
当n为合数时,若存在
a
∈
B
(
n
)
a\in B(n)
a∈B(n),则n被称为以a为底的强伪素数
n为素数,则n对所有底均为强伪素数
一般来说,强伪证据比较少,可以确定,当n是任一大于4的奇素数时,强伪证据不超过1/4。故用强伪证据判断,正确概率可以达到3/4
综上,该算法是一个3/4正确、偏假的算法。若重复调用k次后返回true,则出错的概率为
(
1
/
4
)
k
(1/4)^k
(1/4)k。
故RepeatMillRob(k)是
1
−
(
1
/
4
)
k
1-(1/4)^k
1−(1/4)k-正确的MC算法
时间复杂度为 O ( l g 3 n l g 1 / ϵ ) O(lg^3nlg1/\epsilon) O(lg3nlg1/ϵ)
- 矩阵乘法验证
1)问题描述:判定AB=C,ABC都是方阵
2)MC算法:改为判断XAB=XC,其中X为1*n
3)算法分析:显然是一个偏假的算法,1/2-correct
4)依然是重复多次可以降低出错概率