Problem
质因子分解一个给定的很大的
Solution
Part I:质数判定 Miller-Rabin算法
费马小定理
,逆定理成立的概率也很大。 如果任意选择一个数字,发现,那么就有很大概率是个质数。如果随机地多取几个,那么出错的概率会大大减小。 但是仍然有一些合数,满足对于。这些数字成为Carmichael数。为了把这些数字也正确地判断掉,引入了
二次探测定理
是一个质数,那么的解。 也就是说如果且,那么不是质数。
做法
所以就随机选几个数字,用费马小定理结合二次探测定理来测试一下。 具体的做法,就是提取中的,把化为的形式 求出,一路平方,如果出现了而,就不是质数。 最后会得到,再看看这个是不是。
Part II:寻找因子 Pollard-Rho算法
寻找因子,试除法的复杂度是的,处理不了64位整数的范围。 于是Pollard-Rho诞生了
生日悖论
从里面选两个数,两个数字相等的概率是 但如果从里面选三个数,使得前两个数字的差等于第三个数,那么概率就能增加不少,因为每个数对应着两个和它差值为一个定值的数。 如果选的更多,那么概率就更大。用一个通俗的模型解释,就是在人中,有的概率出现两个人生日在同一天,然后这似乎并不符合常理,所以就是生日悖论。
Pollard-Rho
提到了生日悖论,多半是要用基于概率的算法了。。大体的做法就是遍历一个随机数序列,看相邻两项的差与给定是否互质,如果不互质,就找到了一个因数。 因为随机数序列存不下,那就一项一项地生成,但是随机数序列会有周期,会卡在里面出不来。 而由于空间限制,判周期只能用Floyd套圈法,那就稍微改变一下策略,让两个指针在随机数序列上分别一次走一步、走两步,直到差与不互质。(注:) 在实现的时候,有一个优化。两个指针同时走,会重复地计算很多个项。那么只让一个指针走,另一个指针在它走了步之后一步走过去。具体见代码。这个优化的正确性应该比较显然,但是还没有细想会不会产生一些退化的情况。
Code
1 |
|