码迷,mamicode.com
首页 > 编程语言 > 详细

【快速因数分解】Pollard's Rho 算法

时间:2016-04-22 19:57:18      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:

算法目的

给一个数n,快速提取n的一个因数。

算法根据:生日悖论

讲生日悖论之前,先看一个东西。
给出[1..1000]的数,从中任意选出一个数为k的概率是11000
但是假如选出两个数p,q要求他们的差值为k,就是|p-q|=k的概率大概是1500,因为要去绝对值。
继续向下,选出l个数,使他们之间有两个数的差值为k,那么概率会随l的变大而变大,最终会趋近于1。
接下来是生日悖论:
我们随机选择一名学生,他的生日为 4 月 1 日的概率为 [1..365]
这相当于我们在[1..365]中随机选取一个数,该数为 90 的概率是多少?
那么我们又回到了上面那个问题。
我们随机选取 k(k≥ 2)个人 ,他们的生日相同的概率是多少(就是差值为0)?
我们可以看到,k = 10 的时候大概有 11%的可能性存在两个人生日相同的情况,
而 k = 23 时,可能性提高至50%,假如一个班级总共有57个人,而l=57时的可能性已达到99%,几乎可以肯定地说,一个班级里必定有两个同学的出生日期是相同的,而这么多年的求学生涯过来了,这个概率“似乎”是不正确的,这便是悖论了。

Pollard’s Rho 算法

那么竟然有了这个玄学的悖论,我们就可以随机的快速分解n了,2333。
有一个随机函数f(x)=(x*x+d)%n,d=rand()。然后每次随机出来的数和上一次随机出来的数的差值与n去一个最大公因数,然后判断一下就好了。
但是假如一直找不到符合的数然后死循环了怎么办。
我们可以用Floyd发明的机智判环算法,因为我每次a=f(a),再找一个b=f(f(b)),如果有一个时刻a=b那么就退出循环,因为b是以两倍的速度走得,当b追上了a,那么b至少已经走完一圈了。
复杂度O(n14),看上去O(玄学)。

Code

随机函数f

ll f(ll x){
    int u=rand();
    return (cheng(x,x,n)+po)%n;
}

Pollard’s Rho 算法

a=0;
    b=1;
    po=rand()%n+1;
    while(1){
        a=b=rand()%n+1;
        while(1){
            a=f(a);
            b=f(f(b));
            if(a==b)break;
            ll ui=abs(b-a);
            ll tt=gcd(ui,n);
            if(tt==1||tt==n)continue;
            if(tt>1){
                p=tt;
                break;
            }
        }  
        po--;
        if(p)break;
    }

【快速因数分解】Pollard's Rho 算法

标签:

原文地址:http://blog.csdn.net/doyouseeman/article/details/51204612

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!