Тест на простоту AKS (также известный как тест на простоту Агравала–Каяла–Саксены и циклотомический тест AKS ) — это детерминированный алгоритм доказательства простоты, созданный и опубликованный Маниндрой Агравалом , Нираджем Каялом и Нитином Саксеной , специалистами по информатике из Индийского технологического института в Канпуре , 6 августа 2002 года в статье под названием «PRIMES is in P». [1] Этот алгоритм был первым, который способен за полиномиальное время определить , является ли заданное число простым или составным , и это без опоры на математические гипотезы, такие как обобщенная гипотеза Римана . Доказательство также примечательно тем, что не опирается на область анализа . [2] В 2006 году авторы получили за свою работу как премию Гёделя , так и премию Фулкерсона .
AKS — первый алгоритм доказательства простоты, который одновременно является общим , полиномиальным , детерминированным и безусловно правильным . Предыдущие алгоритмы разрабатывались на протяжении столетий и достигли максимум трех из этих свойств, но не всех четырех.
Хотя алгоритм имеет огромное теоретическое значение, он не используется на практике, что делает его галактическим алгоритмом . Для 64-битных входных данных тест Бейли–PSW является детерминированным и выполняется на много порядков быстрее. Для больших входных данных производительность тестов ECPP и APR (также безусловно верных) намного превосходит AKS. Кроме того, ECPP может выводить сертификат простоты , который позволяет проводить независимую и быструю проверку результатов, что невозможно с алгоритмом AKS.
Тест простоты AKS основан на следующей теореме: если задано целое число и целое число , взаимно простое с , то является простым тогда и только тогда, когда выполняется полиномиальное отношение конгруэнтности
выполняется внутри кольца многочленов . [1] Обратите внимание, что обозначает неопределенность , которая порождает это кольцо многочленов.
Эта теорема является обобщением малой теоремы Ферма на многочлены . В одном направлении ее можно легко доказать, используя биномиальную теорему вместе со следующим свойством биномиального коэффициента :
Хотя соотношение ( 1 ) само по себе представляет собой тест на простоту, его проверка занимает экспоненциальное время : метод грубой силы потребовал бы расширения многочлена и уменьшения результирующих коэффициентов.
Конгруэнтность — это равенство в кольце многочленов . Оценка в фактор-кольце создает верхнюю границу для степени вовлеченных многочленов. AKS оценивает равенство в , делая вычислительную сложность зависимой от размера . Для ясности [1] это выражается как конгруэнтность
что то же самое, что:
для некоторых полиномов и .
Обратите внимание, что все простые числа удовлетворяют этому соотношению (выбор в ( 3 ) дает ( 1 ), что справедливо для простых чисел). Это сравнение можно проверить за полиномиальное время, когда является полиномиальным по отношению к цифрам числа . Алгоритм AKS оценивает это сравнение для большого набора значений, размер которого является полиномиальным по отношению к цифрам числа . Доказательство валидности алгоритма AKS показывает, что можно найти и набор значений с указанными выше свойствами, такие, что если сравнения выполняются, то является степенью простого числа. [1]
В первой версии цитируемой выше статьи авторы доказали, что асимптотическая временная сложность алгоритма равна (используя Õ из нотации O большое ) — двенадцатой степени числа цифр в n , умноженной на полилогарифмический по числу цифр множитель. Однако эта верхняя граница была довольно свободной; широко распространенная гипотеза о распределении простых чисел Софи Жермен , если она верна, немедленно сократила бы наихудший случай до .
В течение месяцев после открытия появились новые варианты (Lenstra 2002, Pomerance 2002, Berrizbeitia 2002, Cheng 2003, Bernstein 2003a/b, Lenstra и Pomerance 2003), которые значительно улучшили скорость вычислений. В связи с существованием множества вариантов, Крэндалл и Пападопулос ссылаются на "AKS-класс" алгоритмов в своей научной статье "О реализации тестов простоты AKS-класса", опубликованной в марте 2003 года.
В ответ на некоторые из этих вариантов и на другие отзывы статья «PRIMES is in P» была обновлена с новой формулировкой алгоритма AKS и доказательством его корректности. (Эта версия была в конечном итоге опубликована в Annals of Mathematics .) Хотя основная идея осталась прежней, r было выбрано по-новому, а доказательство корректности было организовано более последовательно. Новое доказательство опиралось почти исключительно на поведение циклотомических многочленов над конечными полями . Новая верхняя граница временной сложности была , позже уменьшена с использованием дополнительных результатов из теории решета до .
В 2005 году Померанс и Ленстра продемонстрировали вариант AKS, который работает в операциях, [3] что привело к появлению еще одной обновленной версии статьи. [4] Агравал, Кайал и Саксена предложили вариант, который работал бы, если бы гипотеза Агравала была верна; однако эвристический аргумент Померанса и Ленстры показал, что он, вероятно, ложный.
Алгоритм следующий: [1]
Здесь ord r ( n ) — мультипликативный порядок n по модулю r , log 2 — двоичный логарифм , а — функция Эйлера от r .
Шаг 3 показан в статье как проверка 1 < ( a , n ) < n для всех a ≤ r . Видно, что это эквивалентно пробному делению до r , которое можно выполнить очень эффективно без использования gcd . Аналогично сравнение на шаге 4 можно заменить тем, что пробное деление вернет простое число после проверки всех значений до и включая
После очень малых входов, шаг 5 доминирует по времени. Существенное снижение сложности (от экспоненциальной до полиномиальной) достигается путем выполнения всех вычислений в конечном кольце
состоящий из элементов. Это кольцо содержит только одночлены , а коэффициенты находятся в , в котором есть элементы, все они кодируются в битах.
Большинство более поздних улучшений алгоритма были сосредоточены на уменьшении размера r, что ускоряет основную операцию на шаге 5, и на уменьшении размера s , количества циклов, выполняемых на шаге 5. [5] Обычно эти изменения не изменяют вычислительную сложность, но могут привести к сокращению затрачиваемого времени на много порядков; например, окончательная версия Бернштейна имеет теоретическое ускорение более чем в 2 миллиона раз.
Чтобы алгоритм был правильным, все шаги, определяющие n, должны быть правильными. Шаги 1, 3 и 4 тривиально правильны, поскольку они основаны на прямых тестах делимости n . Шаг 5 также правильный: поскольку (2) верно для любого выбора взаимно простого числа с n и r , если n — простое, неравенство означает, что n должно быть составным.
Трудная часть доказательства — показать, что шаг 6 верен. Его доказательство правильности основано на верхней и нижней границах мультипликативной группы , построенной из ( X + a ) двучленов, которые проверяются на шаге 5. Шаг 4 гарантирует, что эти двучлены являются различными элементами . Для конкретного выбора r границы приводят к противоречию, если только n не является простым числом или степенью простого числа. Вместе с проверкой шага 1 это означает, что n всегда является простым числом на шаге 6. [1]
Вход : целое число n = 31 > 1. (* Шаг 1 *) Если ( n = a b для целых чисел a > 1 и b > 1), выведите составное . Для (b = 2; b <= log 2 (n); b++) { a = n 1/b ; Если (a — целое число), вернуть [Composite] } а = n 1/2 ...n 1/4 = {5,568, 3,141, 2,360} (* Шаг 2 *) Найдите наименьшее r такое, что O r ( n ) > (log 2 n ) 2 . макск = ⌊(log 2 n) 2 ⌋; maxr = Max[3, ⌈(Log 2 n) 5 ⌉]; (* maxr на самом деле не нужен *) следующийR = Истина; Для (r = 2; nextR && r < maxr; r++) { следующийR = Ложь; For (k = 1; (!nextR) && k ≤ maxk; k++) { следующийR = (Mod[n k , r] == 1 || Mod[n k , r]==0) } } r--; (*цикл увеличивается на единицу*) г = 29 (* Шаг 3 *) Если (1 < gcd ( a , n ) < n для некоторого a ≤ r ), вывести составное число . Для (a = r; a > 1; a--) { Если ((gcd = GCD[a,n]) > 1 && gcd < n), Вернуть [Составное число] } НОД = {НОД(29,31)=1, НОД(28,31)=1, ..., НОД(2,31)=1} ≯ 1 (* Шаг 4 *) Если ( n ≤ r ), вывести простое число . Если ( n ≤ r), вернуть [Простое число] (* этот шаг можно пропустить, если n > 5690034 *) 31 > 29 ( * Шаг 5 *) Для a = 1 выполнить If (( X + a ) n ≠ X n + a (mod X r − 1, n )), вывести составной ; φ[x_] := ЭйлерФи[x]; PolyModulo[f_] := PolynomialMod[ PolynomialRemainder [f, x r -1, x], n]; max = Floor[Log[2, n] √ φ[r] ]; For (a = 1; a ≤ max; a++) { If (PolyModulo[(x+a) n - PolynomialRemainder[x n +a, x r -1], x] ≠ 0) { Return [Composite] { } (х+а) 31 = а 31 +31а 30 х +465а 29 х 2 +4495а 28 х 3 +31465а 27 х 4 +169911а 26 х 5 +736281а 25 х 6 +2629575а 24 х 7 +7888725а 23 х 8 +20160075а 22 х 9 +44352165а 21 х 10 +84672315а 20 х 11 +141120525а 19 х 12 +206253075а 18 х 13 +265182525а 17 х 14 +300540195а 16 х 15 +300540195а 15 х 16 +265182525a 14 х 17 +206253075a 13 х 18 +141120525a 12 х 19 +84672315a 11 х 20 +44352165a 10 х 21 +20160075a 9 х 22 +7888725a 8 х 23 +2629575a 7 х 24 +736281a 6 х 25 +169911a 5 х 26 +31465a 4 х 27 +4495a 3 х 28 +465a 2 х 29 +31ax 30 +x 31 ПолиномиальныйОстаток [(x+a) 31 , x 29 -1] = 465a 2 +a 31 +(31a+31a 30 )x +(1+465a 29 )x 2 +4495a 28 x 3 +31465a 27 x 4 +169911a 26 x 5 +736281a 25 x 6 +2629575a 24 x 7 +7888725a 23 x 8 +20160075a 22 x 9 +44352165a 21 x 10 +84672315a 20 x 11 +141120525a 19 x 12 +206253075a 18 x 13 +265182525a 17 x 14 +300540195a 16 х 15 +300540195a 15 х 16 +265182525a 14 х 17 +206253075a 13 х 18 +141120525a 12 х 19 +84672315a 11 х 20 +44352165a 10 х 21 +20160075a 9 х 22 +7888725a 8 х 23 +2629575a 7 х 24 +736281a 6 х 25 +169911a 5 х 26 +31465a 4 х 27 +4495a 3 х 28 ( A ) ПолиномиальныйMod [Остаток Полинома [(x+a) 31 , x 29 -1], 31] = a 31 +x 2 ( B ) ПолиномиальныйОстаток [x 31 +a, x 29 -1] = a+x 2 ( А ) - ( В ) = а 31 + х 2 - (а + х 2 ) = а 31 - а {1 31 -1 = 0 (по модулю 31), 2 31 -2 = 0 (по модулю 31), 3 31 -3 = 0 (по модулю 31), ..., 26 31 -26 = 0 (по модулю 31)} (* Шаг 6 *) Вывести простое число . 31 Должно быть простое число
Где PolynomialMod — это почленное уменьшение по модулю полинома. Например, PolynomialMod[x+2x 2 +3x 3 , 3] = x+2x 2 +0x 3
[6]