Pollard Rho因子分解算法 Miller-Rabin算法

  有一类问题,要求咱们将一个正整数x,分解为两个非平凡因子(平凡因子为1与x)的乘积x=ab。html

  显然咱们须要先检测x是否为素数(若是是素数将无解),可使用Miller-Rabin算法来进行测试。算法

  Pollard Rho是一个很是玄学的方式,用于在O(n^1/4)的指望时间复杂度内计算合数n的某个非平凡因子。事实上算法导论给出的是O(√p),p是n的某个最小因子,知足p与n/p互质。可是这些都是指望,未必符合实际。但事实上Pollard Rho算法在实际环境中运行的至关不错。dom

  Pollard Rho利用伪随机数生成公式来提供待测因子,其公式为xi=xi-1^2+c(mod n),其中c是开始时确认的随机常数。咱们只要给出x1,利用这个公式能够生成一系列数值。因为每一个数彻底依赖于前一个数,所以数值的分布中一定含环,咱们设t为环的路口,u为环的周长,那么有xt+i=xt+u+i。而整个数值分布就像一个ρ符号,所以该算法的后缀用Rho来表示。咱们将该公式得出的序列视做随机序列。post

  生日悖论中指出一个√d个学生的班级中,指望至少有一对人在同一天生日,其中d是一年中的日期,即365。一样一个√d我的的班级中,至少有一对人在同一天生日的几率大于50%。咱们将n视做一年中的天数,而1~n-1中的每一个值都对应一年中的日期,将x1,x2,...视做学生,那么序列中指望有两个有两我的相同,只须要序列的长度达到√n便可。所以咱们能够认为ρ符号的尾部与环的周长的指望均为√n。测试

  假设n=ab,其中a与b均不是n的平凡因子,咱们假设a<=b,可知a<=√n。咱们记yi=xi(mod a)。可知:url

$$ y_i=x_i\left(mod\ a\right)=\left(x_{i-1}^2+c\right)\left(mod\ n\right)\left(mod\ a\right)=\left(x_{i-1}^2+c\right)\left(mod\ a\right) $$ $$ =\left(\left(x_{i-1}\left(mod\ a\right)\right)^2+c\right)\left(mod\ a\right)\Rightarrow\left(y_{i-1}^2+c\right)\left(mod\ a\right)=y_i\left(mod\ a\right) $$spa

  咱们依据a为模数创建了新的一个ρ型轨迹,且a的ρ型轨迹的环必然仅出现n的ρ型轨迹的环上的数值(模a的结果)。由一样的分析可得a的ρ型轨迹的环的尾部和环的长度的指望均为n^(1/4)。对于a的ρ型轨迹的环上的任意一点k,假设其对应的是两个不一样的值xi与xj,即xi<>xj(mod n)但xi=xj(mod a)。此时能够知(xi-xj)=rp(mod n),而gcd(xi-xj, n)的结果必然是n的一个非平凡因子(且能被a整除)。咱们能够利用一个特定的变量p前后在迭代到x1,x2,x4,x8,...时记录这些值,以后每次都校验gcd(xi-p, n)是否既非1又非n,若是知足则找到n的非平凡因子,不然继续迭代。以前说过a的ρ型轨迹的环的尾部和环的长度的指望均为n^(1/4),所以当咱们p记录xh时,其中xh落在a的ρ型轨迹的环上且h大于等于环的周长时,此时咱们会沿着a的ρ型轨迹的环进行周而复始的循环迭代,最终在修改p以前xi回到了xh的位置,此时借助gcd(xi-p, n)咱们就找到了一个n的非平凡因子。h的指望应该为O(n^(1/4)),所以时间复杂度的指望应该为O(n^(1/4))。code

  下面给出代码:htm

pollard_rho(x)
    c = random()
    xi = random()
    i = 1
    h = 1
    xh = xi
    while(true)
        xi = (xi * xi + c) % n
        f = gcd(x, abs(xi - xh))
        if(f != 1 && f != n)
            return f
        i = i + 1
        if( i == h * 2)
            h = i
            xh = xi
相关文章
相关标签/搜索