对Pollard's Rho算法的理解

之前曾经碰到过要用到Pollard's Rho算法的题目,不过当时没有学这个算法,只是备忘了一下,这两天没事干把这个算法学了。wiki上说这个算法是一个通用的因数分解算法,对于分解因子较小的组合数特别有用。

对于一个正整数n,在一般情况下,我们主要使用的是枚举1到n^(1/2)来求n的因子,所以算法复杂度是O(n^(1/2))。但是实际上有更好的办法,那就是Pollard's Rho算法,这个算法是一个随机化的算法,简单的说不是完全靠谱,一般我们认为它的平均算法复杂度是O(n^(1/4)),在64位范围内都是很开心的。

这个算法应用了一个非常神奇的思想——Birthday Trick。对于一个特定的目标值Aim,简单的一次随机企图命中它的概率是1/n,但是随机抽取k个值,这k个值中某两个值的差值命中Aim的概率却在k约为n^(1/2)时达到1/2。如果我们视n的因子为Aim(如果有的话),便可以用这个方法找到它了。

实际上上述算法的复杂度是O(n),因为有k=n^(1/2)。又总共要比较k*k/2次。于是要优化。这里一个重要的思路是对于一个合数n,设p和q是它的两个因子,那么n与p的倍数和q的倍数有最大公约数大于1(为p或q)。现在我们只要要求k个随机值中某两个数的差值是p或q的倍数就行了。然后就有k的取值下降到n^(1/4),具体怎么算出来的我看不懂,就不深究了。

第二个重要优化是如何储存k个数,实际上没有必要储存下来,因为它们是随机数,我们只要用一个随机函数不断生成它们就好了,这里一般用f(x) = (x * x + a)  mod N来生成伪随机数。注意到这里我们放弃了两两比较k个数,只是比较k个数中相邻的两个,这样也可以?我不知道。

在下来的一个问题是f的生成序列有可能是一个环,这就要求我们再加一个floyd的算法来判环。

这样就有一个可以在O(n^(1/4))时间内有1/2概率找出n的因子的算法了。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页