2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу Пред.  1 ... 50, 51, 52, 53, 54, 55, 56 ... 58  След.
 
 Re: Как писать быстрые программы
Сообщение12.03.2026, 23:16 
wrest в сообщении #1720079 писал(а):
Это муторно мне
Однако сравнивать надо одинаковые вещи - поиск первого делителя. А не поиск первого с полной факторизацией. Или тогда берите полупростые числа (произведение двух простых), где полная факторизация совпадает с поиском первого делителя.

wrest в сообщении #1720079 писал(а):
поллард быстрее :D
:facepalm:

 
 
 
 Re: Как писать быстрые программы
Сообщение12.03.2026, 23:29 
Dmitriy40 в сообщении #1720080 писал(а):
Однако сравнивать надо одинаковые вещи - поиск первого делителя.

Да-да. Это шутка была. :oops:

Но вообще у меня мелькала мысль предложить Yadryara вместо полларда попробовать omega_upto()
Но дело в том, что в omega_upto(), если мне не изменяет память, я не отключил словарную проверку (не было такой задачи). И мне кажется, что поллард это хороший выбор под узкую задачу поискать чуток дальше чем $2^{20}$. Тем более что оказалось, что есть поллард встроенный.

 
 
 
 Re: Как писать быстрые программы
Сообщение12.03.2026, 23:48 
Что интересно, под виндой тоже работает:
Код:
? install(Z_pollardbrent,GLL)
? Z_pollardbrent(15621763*614813194568884725330347254101670326647553073,10^2,1)
%2 = [15621763, 614813194568884725330347254101670326647553073]

 
 
 
 Re: Как писать быстрые программы
Сообщение12.03.2026, 23:57 
Dmitriy40 в сообщении #1720085 писал(а):
Что интересно, под виндой тоже работает:

Так и должно быть, для функций в libpari.

-- 13.03.2026, 00:49 --

Dmitriy40
Кстати, вот если включить \g 4 то можно увидеть что
factor(9604466014828004353430781511277071747020658636327699)
находит первый мелкий множитель именно поллардом. у меня в логе это 13мс:
Код:
? factorint(9604466014828004353430781511277071747020658636327699)
IFAC: cracking composite
        9604466014828004353430781511277071747020658636327699
IFAC: checking for pure square
IFAC: trying Pollard-Brent rho method
Rho: searching small factor of 173-bit integer
Rho: using X^2+7 for up to 4327 rounds of 32 iterations
Rho: time =     13 ms,  371 rounds
        found factor = 15621763

если отключить полларда, то находит первый множитель ECM-ом но уже за 26мс:
Код:
? factorint(9604466014828004353430781511277071747020658636327699,4)
IFAC: cracking composite                                                                                                                             9604466014828004353430781511277071747020658636327699
IFAC: checking for pure square
IFAC: trying Lenstra-Montgomery ECM
ECM: working on 8 curves at a time; initializing for up to 3 rounds...
ECM: time =      0 ms
ECM: B1 =  700, B2 =  77000,    gss =  128*420
ECM: time =     26 ms
found factor = 15621763


Отсюда такой вывод: на финальной, 7 фильтрации (в терминах Yadryara), надо отключать полларда т.к. он уже испробован на 6-й фильтрации.

 
 
 
 Re: Как писать быстрые программы
Сообщение13.03.2026, 05:04 
Аватара пользователя
wrest в сообщении #1720064 писал(а):
Dmitriy40 в сообщении #1720055 писал(а):
А чем Поллард быстрее ECM?

Ну алгоритм простой. Он ищет один небольшой множитель и останавливается. Это быстро и удобно.

Наконец-то уважаемый wrest стал гораздо лучше понимать что я делаю.

Применение Полларда, причем именно такого, с такими настройками, позволило выполнить 6-ю фильтрацию вчетверо быстрее: за 11 секунд вместо 46.

Дмитрий, видимо, ошибочно думает, что имеются какие-то сильно длинные факторы, которые лучше находить через ECM.

Но посмотрите на таблицу, на предпоследний столбец. Из 53 цепочек, одна была с 2-значным фактором, ещё 51 с 7-9-значными факторами и лишь одна с 10-значным фактором.

То есть в теории конечно может встретиться разложение 54-значного числа (а это пока максимум, см. последний столбец) на два 27-значных, но на практике я не увидел ни одного даже 11-значного фактора, не говоря уж о более длинных. Да, выборка небольшая. И 11-12-значные факторы видимо тоже встречаются. Но про более длинные для данной задачи можно смело забыть.

 
 
 
 Re: Как писать быстрые программы
Сообщение13.03.2026, 08:29 
Если я правильнотпонял тут и далее
Dmitriy40 в сообщении #1711871 писал(а):
Теория говорит что получится список возрастающих простых - как уже и есть.

Потому что m взаимно простое с любым простым больше 53 и значит остатки по таким простым от n распределены равномерно и значит остаток 0 встречается не чаще других и значит вероятность его обнаружить равна 1/p для простого p.
То фильтрации основанные на том, что сперва надо отсеять мелкие множители т.к. мелкие множители быстрее искать и их больше - это правильный подход.
И тут получается так, что скажем для множителей до $2^{20}$ быстрее всего просто их перебор по предвычисленной таблице. Далее -- Поллард ро. Затем - некий "предварительный" ECM. Затем квадратичное сито MPQS, и потом "тяжелый" ECM. Ровно так, похоже, и раскладывает встроенный в pari/gp движок факторизации.
Но в нашем случае ещё есть нюанс: надо остановить разложение если случился перебор по количеству найденных множителей. На табличном поиске и полларде это делать оказалось элементарно легко.
Так что пока, видимо, правильной дорогой идёте, товарищи :D

-- 13.03.2026, 08:48 --

Yadryara в сообщении #1720089 писал(а):
Дмитрий, видимо, ошибочно думает, что имеются какие-то сильно длинные факторы, которые лучше находить через ECM.

Длинные тоже есть, но их мало и искать их долго. Поэтому их искать надо на поздних стадиях подходящими методами (MPQS, затем ECM)

 
 
 
 Re: Как писать быстрые программы
Сообщение13.03.2026, 09:07 
Аватара пользователя
wrest в сообщении #1720094 писал(а):
Длинные тоже есть, но их мало и искать их долго. Поэтому их искать надо на поздних стадиях подходящими методами (MPQS, затем ECM)

Скорее всего, их искать пока что вообще не надо. Потому что с короткими факторами ещё не разобрались.

Вы упускаете из виду важный момент. После пяти фильтраций остались только числа, у которых пока что найденных факторов либо на 1, либо на 2, либо на 3 меньше чем надо.

6-я фильтрация проверяет только числа, у которых найденных факторов ровно на 1 меньше чем надо.

7-я фильтрация проверяет только числа, у которых найденных факторов ровно на 3 меньше чем надо.

 
 
 
 Re: Как писать быстрые программы
Сообщение13.03.2026, 11:24 
Аватара пользователя
Сортировка не сильно помогла. Кстати первый аспект оказался сильнее: начинать проверку всё-таки чуть лучше с больших чисел.

И если взять ту же 21 константу и 1500 итераций, то удаётся ещё сильнее сократить время: суммарно 6-я и 7-я фильтрация теперь занимают на том же объёме 7-8 секунд, при этом уже чуть больше, а именно 7 чисел из 57 через фильтр проскочили.
Может можно и ещё больше пропустить, но зато ускорить 7-ю фильтрацию.

Yadryara в сообщении #1720095 писал(а):
7-я фильтрация проверяет только числа, у которых найденных факторов ровно на 3 меньше чем надо.

Если алгоритм Полларда настолько успешен, то надо применить его и на 7-й фильтрации: проверять только числа, у которых найденных факторов ровно на 2 меньше чем надо. Находить один фактор, а затем проверять и его и кофактор на псевдопростоту.

 
 
 
 Re: Как писать быстрые программы
Сообщение13.03.2026, 12:49 
Yadryara в сообщении #1720100 писал(а):
Если алгоритм Полларда настолько успешен, то надо применить его и на 7-й фильтрации: проверять только числа, у которых найденных факторов ровно на 2 меньше чем надо. Находить один фактор, а затем проверять и его и кофактор на псевдопростоту.

Надо держать в уме тот факт, что поллардом бцстро находятся "небольшие" множители. Как я понимаю, в той инкарнации котору вам написал Qwen, а так же во встроенной Z_pollaerdbrent(), алгоритм останавливается если найден один [простой] множитель (хотя в описании ко встроенной говорится что иногда он находит два). Вот исходя из этого и надо применять. Если в остатк (частном) не хватает три множителя, то надо попробовать поллардом, и если он нашёл один [простой], попробовать найти в остатке(частном) и второй. Если второй не найден за приемлемое время, хотя известно что остаток (частное) составной, то значит имеет смысл перейти к следующему алгоритму -- MPQS или ECM. Кстати для ECM тоже есть встроенная функция, и она работает детерминистки (ограниченное время), ищет один множитель, не продолжая если нашёлся.
Цитата:
GEN Z_ECM(GEN N, long n, long seed, ulong B1) try to factor t_INT N using $n \ge 1$ rounds of ECM iterations (on 8 to 64 curves simultaneously, depending on the size of N); seed is an integer whose value selects the curves to be used: increase it by $64n$ to make sure that a subsequent call with a factor of N uses a disjoint set of curves. Finally $B_1 > 7$ determines the computations performed on the curves: we compute $[k]P$ for some point in $E(\mathbb{Z}/N \mathbb{Z})$ and $k = q\prod p^{e_p}$ where $p^{e_p} \le B_1$ and $q \le B_2 := 110B_1$; a higher value of $B_1$ means higher chances of hitting a factor and more time spent. The computation is deterministic for a given set of parameters. Returns NULL on failure, else a nontrivial factor or N.

Но тут надо понять что значат параметры и какими их нам надо установить.

 
 
 
 Re: Как писать быстрые программы
Сообщение13.03.2026, 13:03 
Аватара пользователя
wrest, да вы правы, ибо

Yadryara в сообщении #1720100 писал(а):
Если алгоритм Полларда настолько успешен, то надо применить его и на 7-й фильтрации: проверять только числа, у которых найденных факторов ровно на 2 меньше чем надо. Находить один фактор, а затем проверять и его и кофактор на псевдопростоту.

Уже проверил, причём уже по всем остальным местам: фильтрует или долго или слабо.

То есть всё-таки приближения остаются в количестве большем чем надо.

Ну думаю, что если 2-й раз на Полларда отправлять, то уже достаточная фильтрация будет.

Боюсь я этих феликсов :-) Или как правильно, элебз? :-)

 
 
 
 Re: Как писать быстрые программы
Сообщение13.03.2026, 15:30 
Yadryara в сообщении #1720106 писал(а):
Уже проверил, причём уже по всем остальным местам: фильтрует или долго или слабо.

Ну это вы Qwen-овским поллардом проверили? Теперь надо проверить встроенным.
См. тут: post1720046.html#p1720046

 
 
 
 Re: Как писать быстрые программы
Сообщение13.03.2026, 15:37 
Yadryara в сообщении #1720089 писал(а):
Дмитрий, видимо, ошибочно думает, что имеются какие-то сильно длинные факторы, которые лучше находить через ECM.
Дмитрий ошибочно думает что относительно большие делители (больше ~10 цифр) быстрее найдутся методом ECM чем Поллардом, и что таких чисел в цепочке "почти все", т.е. нет чисел с меньшими делителями (или они не дают причины отбросить цепочку). Вот с последним видимо я и ошибаюсь, похоже в цепочках достаточно часто есть числа с малым делителем (до 10-12 цифр), который методом Полларда находится быстрее чем ECM. Ну я же тестов не проводил ...

wrest в сообщении #1720094 писал(а):
Затем квадратичное сито MPQS, и потом "тяжелый" ECM. Ровно так, похоже, и раскладывает встроенный в pari/gp движок факторизации.
PARI второй раз ECM запускает не в качестве "тяжёлой артиллерии", а для разложения найденных предыдущими методами делителей на простоту - надеюсь Вы все в курсе что Поллард (да и ECM) могут найти/вернуть составной делитель. Вот для таких и запускается финальный ECM, доразложить найденные делители на простые. Кстати про PARI примеров нет, а вот для YAFU в логах остался пример когда ECM нашёл составной делитель и запустился рекурсивно уже для него (у меня аж глаза на лоб полезли пока не понял что происходит).

wrest в сообщении #1720104 писал(а):
хотя в описании ко встроенной говорится что иногда он находит два
Так второй получается банальным делением исходного числа на найденный первый делитель. И оба в принципе могут быть составными.

Yadryara, wrest
Ещё момент: и ECM и Поллард зависят от некоторого числа seed, при смене которого делители находятся по другому (пример с Поллардом показывал Yadryara вчера же), так что возможно есть смысл разбить одну проверку на несколько одинаковых меньших, но с разными seed. Практика показывает что иногда ECM (в реализации YAFU где seed случайный) находит делители на порядки быстрее, вот буквально на порядки. Нечасто, да и не факт что будет выигрыш общего времени, но стоит держать факт в уме.

 
 
 
 Re: Как писать быстрые программы
Сообщение13.03.2026, 16:01 
Dmitriy40 в сообщении #1720120 писал(а):
Так второй получается банальным делением исходного числа на найденный первый делитель. И оба в принципе могут быть составными.

Не-не, написано так:
Цитата:
Returns NULL on failure, else a vector of 2 (possibly 3) integers whose product is N.


-- 13.03.2026, 16:03 --

Dmitriy40 в сообщении #1720120 писал(а):
и ECM и Поллард зависят от некоторого числа seed, при смене которого делители находятся по другому (пример с Поллардом показывал Yadryara вчера же), так что возможно есть смысл разбить одну проверку на несколько одинаковых меньших, но с разными seed.

Насчёт ECM не знаю, насчёт полларда - Yadryara вроде как в Qwen-овском полларде перебирает seed-ы. Имеет ли это смысл с точки зрения ускорения - не знаю...

-- 13.03.2026, 16:11 --

Dmitriy40 в сообщении #1720120 писал(а):
Вот с последним видимо я и ошибаюсь, похоже в цепочках достаточно часто есть числа с малым делителем (до 10-12 цифр), который методом Полларда находится быстрее чем ECM. Ну я же тестов не проводил ...

Ну поскольку вы раньше писали в том духе (если я опять же правильно понял) что простые в проверяемых числах (остатках/частных, т.е. уже после исключения совсем малых множителей) распределены так же, как и в дикой природе, несмотря на их специальную пре-подготовку ("паттерн"), то малых множителей там больше чем больших.

 
 
 
 Re: Как писать быстрые программы
Сообщение13.03.2026, 16:35 
Аватара пользователя
Чтоб вам не гадать как я считаю. Один из последних вариантов:

Код:
pollardRho_limited(n, maxc, max_iter) = {
    my(c, x, y, d, found = 0);
     
    for(c = 1, maxc,
        x = 2;
        y = 2;
        d = 1;

\\print(c,"   ", n);
       
        for(i = 1, max_iter,
            x = (x^2 + c) % n;           /* Черепаха : 1 шаг  */
            y = ((y^2 + c)^2 + c) % n;   /* Заяц     : 2 шага */
           
            d = gcd(abs(x - y), n);

\\print(n,"   ", x,"   ", y,"   ", abs(x - y),"     ",d);
           
            if(d > 1 && d < n,
                /* Найден нетривиальный делитель */
                return([c, i, d, n/d]);
            );
           
            if(d == n,
                /* Эта константа c не удалась, пробуем следующую */
                break;
            );
        );
    );
   
    /* Ни одна константа не сработала */
    return([0, 0, 0, 0]);
}


wrest в сообщении #1720124 писал(а):
Насчёт ECM не знаю, насчёт полларда - Yadryara вроде как в Qwen-овском полларде перебирает seed-ы. Имеет ли это смысл с точки зрения ускорения - не знаю...

Для, тех чисел с которыми работал — да. Вроде оптимум в районе maxc=21, max_iter=1500 Для других чисел оптимум может быть другим. Да и критерий оптимальности не один.

Видел ссылку на другого Полларда, Спасибо. Глядишь, дойдут руки и до него.

Dmitriy40 в сообщении #1720120 писал(а):
Вот с последним видимо я и ошибаюсь, похоже в цепочках достаточно часто есть числа с малым делителем (до 10-12 цифр), который методом Полларда находится быстрее чем ECM.

В основном 7-8 цифр, иногда 9, особенно если max_iter увеличить.

wrest в сообщении #1720124 писал(а):
Ну поскольку вы раньше писали в том духе (если я опять же правильно понял) что простые в проверяемых числах (остатках/частных, т.е. уже после исключения совсем малых множителей) распределены так же, как и в дикой природе, несмотря на их специальную пре-подготовку ("паттерн"), то малых множителей там больше чем больших.

Ну потому что специальная подготовка в том и заключается, что она касается только малых чисел. Вот только вчера характерный пример привёл. Нынешние паттерны задействуют все малые простые до 73 включительно. А остальные простые числа, начиная с 79 могут вести себя как бы свободно. И вот как раз $79^2$ и встретилось. Могло ли другое простое в квадрате встретиться, которое побольше. Да, конечно. Только вероятность наибольшая именно для 79. $113^2$ встречается уже вдвое реже. Чего уж говорить про числа, которые на порядок-два больше.

-- 13.03.2026, 16:40 --

Кстати, только сейчас заметил: а зачем он d приравнял к единице :-)

 
 
 
 Re: Как писать быстрые программы
Сообщение13.03.2026, 17:17 
Yadryara в сообщении #1720126 писал(а):
Кстати, только сейчас заметил: а зачем он d приравнял к единице :-)

Инициализация переменных это правила хорошего тона.

 
 
 [ Сообщений: 870 ]  На страницу Пред.  1 ... 50, 51, 52, 53, 54, 55, 56 ... 58  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group