#include <iostream>
#include <cstdlib>
typedef unsigned long long int ULL;
ULL gcd(ULL a, ULL b)
{
for(; b >0 ;)
{
ULL rem = a % b;
a = b;
b = rem;
}
return a;
}
void pollard_rho(ULL n)
{
ULL i = 0,y,k,d;
ULL *x = new ULL[2*n];
x[0] = rand() % n;
y = x[0];
k = 2;
while(1){
i = i+1;
std::cout << x[i-1];
x[i] = (x[i-1]*x[i-1]-1)%n;
d = gcd(abs(y - x[i]),n);
if(d!= 1 && d!=n)
std::cout <<d<<std::endl;
if(i+1==k){
y = x[i];
k = 2*k;
}
}
}
int main()
{
srand(time(NULL));
pollard_rho(10);
}
此实施源自CLRS第2版(第894页)。 while(1)
看起来很可疑。 while循环应该是什么终止条件?
我尝试了k<=n
,但这似乎不起作用。我得到分段错误。代码中的缺陷是什么以及如何纠正它?
答案 0 :(得分:1)
为什么存储所有这些中间值?你真的不需要把x和y放在一个数组中。只需使用您继续重复使用的2个变量,x
和y
。
另外,将while(1)
替换为while(d == 1)
并在
if(d!= 1 && d!=n)
std::cout <<d<<std::endl;
if(i+1==k){
y = x[i];
k = 2*k;
所以你的循环应该变成
while(d == 1)
{
x = (x*x - 1) % n;
y = (y*y - 1) % n;
y = (y*y - 1) % n;
d = abs(gcd(y-x,n))%n;
}
if(d!=n)
std::cout <<d<<std::endl;
else
std::cout<<"Can't find result with this function \n";
如果将循环内部使用的函数作为参数传递给pollard
,那么额外的点,如果它无法通过一个函数找到结果,则会尝试另一个函数。
答案 1 :(得分:1)
我只有第一版CLRS,但假设它与第二版没有太大不同,终止条件的答案在下一页:
这个寻找因素的程序起初可能看起来有点神秘。但请注意,POLLARD-RHO从不打印错误答案;它打印的任何数字都是 n 的重要除数。 POLLARD-RHO可能根本不打印任何东西;无法保证会产生任何结果。但是,我们将看到有充分的理由期望POLLARD-RHO在大约sqrt之后打印 n 的 p 因子( p ) while 循环的迭代。因此,如果 n 是复合的,我们可以期望这个过程在大约 n 1/4之后发现足够的除数来完全分解 n 更新,因为 n 的每个主要因子 p 除了可能的最大因素之外都小于sqrt( n )。
因此,从技术上讲,CLRS中的表示没有终止条件(这可能就是为什么他们称之为“启发式”和“程序”而不是“算法”)并且不能保证它永远不会实际上产生任何有用的在实践中,您可能希望根据预期的 n 1/4 更新来设置一些迭代。
答案 2 :(得分:0)
尝试用此替换while(1) { i = i + 1;
:
for (i = 1; i < 2*n; ++i) {