66
Глава 1. Построение абстракций с помощ ью процедур
Тест Ферма производится путем случайного выбора числа a между 1 и n − 1 вклю-
чительно и проверки, равен ли a остаток по модулю n от n -ой степени a. Слу чайное
число a выбирается с помощью процедуры random, про которую мы предполагаем, что
она встроена в Scheme в качестве элементарной процедуры. Random возвращает неот-
рицательное число, меньшее, чем ее целый аргумент. Следовательно, чтобы получить
случайное число между 1 и n −1, мы вызываем random с аргументом n −1 и добавляем
к результату 1:
(define (fermat-test n)
(define (try-it a)
(= (expmod a n n) a))
(try-it (+ 1 (random (- n 1)))))
Следующая процедура прогоняет тест заданное число раз, как указано ее параметром.
Ее значение истинно, если тест всегда проходит, и ложно в противном случае.
(define (fast-prime? n times)
(cond ((= times 0) true)
((fermat-test n) (fast-prime? n (- times 1)))
(else false)))
Вероятностные методы
Тест Ферма отличается по своему характеру от большинства известных алгоритмов,
где вычисляется результат, истинность которого гарантирована. Здесь полученный ре-
зультат верен лишь с какой-то вероятностью. Более точно, если n не проходит тест
Ферма, мы можем точно сказать, что оно не простое. Но то, что n проходит тест, хо-
тя и является очень сильным показателем, все же не гарантирует, что n простое. Нам
хотелось бы сказать, что для любого числа n, если мы проведем тест достаточное ко-
личество раз и n каждый раз его пройдет, то вероятность ошибки в нашем тесте на
простоту может быть сделана настолько малой, насколько мы того пожелаем.
К сожалению, это утверждение неверно. Существуют числа, которые «обманывают»
тест Ферма: числа, которые не являются простыми и тем не менее обладают свойством,
что для всех целых чисел a < n a
n
равно a по модулю n . Такие ч исла очень редки,
так что на практике тест Ферма вполне надежен
47
. Существуют варианты теста Ферма,
которые обмануть невозможно. В таких тестах, подобно методу Ферма, проверка ч исла
n на простоту ведется путем выбора случайного числа a < n и проверки некоторого
условия, зависящего от n и a. (Пример такого теста см. в упражнении 1.28.) С другой
x по модулю m, y по модулю m, перемножения их, и взятия остатка по модулю m от результата. Например, в
случае, когда e четно, мы можем вычислить остаток b
e/2
по модулю m, возвести его в квадрат и взять
остаток по модулю m. Такой метод полезен потому, что с его помощью мы можем производить вычисления, не
используя чисел, намного больших, чем m. (Сравните с упражнением 1.25.)
47
Числа, «обманывающие» тест Ферма, называются числами Кармайкла (Carmichael numbers), и про них
почти ничего неизвестно, кроме того, что они очень редки. Существует 255 чисел Кармайкла, меньших 100
000 000. Несколько первых — 561, 1105, 1729, 2465, 2821 и 6601. При проверке на простоту больших чисел,
выбранных случайным образом, шанс наткнуться на число, «обманывающее» тест Ферма, меньше, чем шанс,
что космическое излучение заставит компьютер сделать ошибку при вычислении «правильного» алгоритма. То,
что по первой из этих причин ал горитм считается неадекватным, а по второй нет, показывает разницу между
математикой и техникой.