У меня есть следующая функция. Я взял его с двух сайтов и попытался адаптировать к своему, но это не очень хорошо сработало.
Когда я проверяю unsigned long int max - 2
или но как число 4294967293
, он помещает следующий код в бесконечный цикл, где ys
будет продолжать возвращаться к тому же значению.
Я очень новичок в алгоритмах факторизации, и пошаговая помощь в том, почему я получаю бесконечный цикл, была бы отличной.
Следующий код - это просто моя функция "ро". У меня есть еще одна функция, называемая 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;
}
Примеры, из которых я адаптировал свой код:
РЕДАКТИРОВАТЬ
Я сделал так, как предложил Амд, привел в порядок свой код и переместил повторяющиеся строки во вспомогательные функции. Однако я все еще получаю бесконечный цикл для части 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;
}
y * y % n
, не вычисляют по модулюn
, еслиn
достаточно велико, за исключением того, что код слишком длинный для серьезной проверки. - person harold   schedule 07.05.2016