【发布时间】:2016-05-07 00:25:10
【问题描述】:
我有以下功能。我从两个网站上得到它,并尝试将其改编为我自己的,但效果不佳。
当我测试 unsigned long int max - 2 或 to 但它作为数字 4294967293 时,它会将以下代码放入无限循环中,ys 将继续返回相同的值。
我对因式分解算法非常陌生,并且逐步帮助我了解为什么我得到无限循环会很棒。
以下代码只是我的“rho”函数。我有另一个名为 gdc 的函数,它与所有其他 gdc 递归函数相同。
unsigned long int rho(unsigned long int n)
{
if (n == 1) return n;
if (n % 2 == 0) return 2;
unsigned long int y = rand() % n;
unsigned long int x;
unsigned long long int ys = y;
unsigned long int c;
do
c = rand() % n;
while (c == 0 || c == n - 2);
unsigned long int m = 1000;
unsigned long int d = 1;
unsigned long int q = 1;
unsigned long int r = 1;
while (d == 1)
{
x = y;
for (int i = 0; i < r; i++)
{
y = y * y % n;
y += c;
if (y < c)
y += (std::numeric_limits<unsigned long>::max() - n) + 1;
y %= n;
}
int j = 0;
while (j < r && d == 1)
{
ys = y;
for (int i = 0; i < m && i < (r-j); i++)
{
y = y * y % n;
y += c;
if (y < c)
y += (std::numeric_limits<unsigned long>::max() - n) + 1;
y %= n;
q *= ((x>y) ? x - y : y - x) % n;
}
d = gcd(q, n);
j += m;
}
r *= 2;
}
if (d == n)
{
do
{
ys = ys * ys % n;
std::cout << ys << std::endl;
ys += c;
if (ys < c)
ys += (std::numeric_limits<unsigned long>::max() - n) + 1;
ys %= n;
d = gcd( ((x>ys) ? x - ys : ys - x) , n);
} while (d == 1);
}
return d;
}
我改编代码的示例:
编辑
我按照 Amd 的建议做了,整理了我的代码,并将重复的行移到了辅助函数中。但是,对于底部附近的 d==n 部分,我仍然会遇到无限循环。出于某种原因,f(ys) 最终返回的内容基本上与之前返回的内容相同,因此它不断循环遍历一系列值。
uint64_t rho(uint64_t n)
{
if (n == 1) return n;
if (n % 2 == 0) return 2;
uint64_t y = rand() % n;
uint64_t x;
unsigned long long int ys = y;
uint64_t c;
do c = rand() % n; while (c == 0 || c == n - 2);
uint64_t m = 1000;
uint64_t d = 1;
uint64_t q = 1;
uint64_t r = 1;
do
{
x = y;
for (int i = 0; i <= r; i++)
y = f(y, c, n);
int j = 0;
do
{
ys = y;
for (int i = 0; i <= min(m, r-j); i++)
{
y = f(y, c, n);
q *= (abs(x,y) % n);
}
d = gcd(q, n);
j += m;
} while (j < r && d == 1);
r *= 2;
} while (d == 1);
if (d == n)
{
do
{
ys = f(ys, c, n);
d = gcd(abs(x, ys), n);
} while (d == 1);
}
return d;
}
【问题讨论】:
-
如果
n足够高,则y * y % n等幼稚表达式不会计算模n,除非代码有点长,需要认真检查 -
好吧,我可以计算 max unsigned long int 就好了。它只是 max unsigned long - 2 失败,所以绝对不是这样
-
它可能会意外工作。这并不正确。
标签: c++ algorithm loops factorization