Pollard的rho啟發式因子分解演算法 & [CodeVS 4939] 尤拉函式:Miller-Rabin + Pollard-rho 質因數分解
Pollard的rho啟發式因子分解演算法用於給出整數的一個因子。在一定的合理假設下,如果n有一個因子p,可在
關於其複雜度,Wikipedia是這樣敘述的:
If the pseudo random number x = g(x) occurring in the Pollard ρ algorithm were an actual random number, it would follow that success would be achieved half the time, by the Birthday paradox in O(p^(1/2)) ≤ O (n^(1/4)) iterations. It is believed that the same analysis applies as well to the actual rho algorithm, but this is a heuristic claim, and rigorous analysis of the algorithm remains open.
以下絕大部分來自《演算法導論》。
Pollard-rho演算法的核心是用遞推式
虛擬碼如下:
Pollard-Rho(n, c)
i = 1
k = 2
y = x = a random integer in [0, n)
d = 1
while d == 1
i = i+1
x = (x*x+c) mod n
if x == y
return n
d = gcd(n, abs(x-y))
if i == k
k = k*2
y = x
return d
它的正確性是顯然的。演算法可能會失敗地返回一個平凡因子n,也可能成功地返回一個n的某個非平凡因子。
設
必有2的某次冪落在區間[t, 2t]內,因此在不超過第2t步,迴圈內的某個值將被儲存。此時的k可能小於C,無妨,因為必有2的某次冪落在區間[C, 2C]內,2C步之內,有k不小於C成立。於是,至多走(2*min(t, C)+C)步,演算法終止。這個演算法叫Brent判圈演算法(Brent’s cycle finding method),與Floyd判圈演算法均為線性,但常數優於後者(至少3C次計算後繼結點)。根據Wikipedia,Pollard的原始版本採用Floyd判圈演算法,後來由Richard Brant用自己新發明的判圈演算法加以改進。
設n有一個因子p,其實我們同時在計算
同樣是ρ形。迴圈內兩個數作差,是p的倍數,和n取gcd,因子p或p的某倍便被呈現出來。與上面的論證類似,進入迴圈後不超過
假設
生日悖論:從n個數中可重複地隨機選擇k個,當
用數學期望描述這個命題:相等數對的數目不少於1。這樣計算起來會簡單一些。
對
令上式
把這個結論運用到我們的問題中來。
至此,一切都看起來很美好。如果n有某個因子p,則