Проверка на простоту чисел тестом Миллера-Рабина: реализация и сравнение.(Miller-Rabin BPSW Test: realization)

Revision ru5, by Tigutor, 2016-01-10 12:01:54

Понадобилось мне сегодня проверить на простоту числа за время, куда меньшее корня квадратного из n, и сразу в голове всплыла статья с emaxx. Полез я туда, скопировал код, а он не работает. И не хотелось в нем разбираться, попытался найти в гугле — там тоже абсолютно ничего по сабжу нет. Вот и решил я написать свою реализацию.. Открыв wikipedia, можно увидеть замечательную запись:

Немного подумав(возведение в степень по модулю — log, предпосчет степеней двойки вообще за const), я порадовался вырисовывавшейся асимптотике и начал писать. Понимая, что на одну проверку уйдет 2log, но вероятность верного определения числа всего 3/4, мною было принято решение производить 5 проверок — в этом случае вероятность неверного решения будет всего 1/1024. Получился следующий код. Далее, была проведена проверка, я сдал задачу

Как мы видим, худший тест выполнился за время чуть более одной секунды, тогда как решение за корень из n работает ровно одну секунду

Я уменьшил количество проверок до 3 и получил полностью рабочее решение с временем около 1с.

Поразительно то, что на таких маленьких входных данных тест Миллера-Рабина работает почти так же быстро, как и проверка за корень! Что уж говорить, что на больших числах проверка за корень не уложится и в 10 секунд, тогда как такой тест сработает за сотые доли секунды. Или, как вариант, найти все простые числа в диапазоне от 10^12 до 10^12 + 10^6

Решето Эратосфена умрет по дороге и из-за огромного количества памяти, и уж тем более по времени — ведь его асимптотика при нахождении всех простых чисел от N до K О(KloglogK), а асимптотика теста Миллера-Рабина — O((K — N)logK), ну и не забываем скрытую константу, равную 10. Внушительная разница, не правда ли?

На этом моё небольшое исследование подошло к концу, буду рад комментариям, оптимизации кода и другим проверкам этого алгоритма.
UPD Благодаря замечанию уважаемого AlexanderBolshakov была решена проблема с переполнением на огромных числах в степени по модулю и исправлено возведение в степень. К сожалению, это увеличило каждый log в асимтотике еще на log, но на огромных числах это не повлияло на время работы. Задача зашла без проблем.

Tags миллер-рабин, тест на простоту, вероятность, bpsw

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
ru5 Russian Tigutor 2016-01-10 12:01:54 421
ru4 Russian Tigutor 2016-01-10 03:49:27 6 Мелкая правка: 'емя, куда большее корня' -> 'емя, куда меньшее корня'
ru3 Russian Tigutor 2016-01-10 03:13:11 203
ru2 Russian Tigutor 2016-01-10 02:55:06 1 Мелкая правка: 'ать свою рализацию..' -> 'ать свою реализацию..'
ru1 Russian Tigutor 2016-01-10 02:53:17 2575 Первая редакция (опубликовано)