Wykorzystanie programu Derive do poszukiwania liczb pierwszych

advertisement
Badanie pierwszości liczby, klasa NP i test Rabina
Antoni Kościelski
Piękno teorii matematycznej nie jest wystarczającym powodem nauczania jej w szkole.
Liczby pierwsze pojawiały się w programach szkolnych przy okazji obliczania wartości
wyrażeń wymiernych. Dzisiaj umiejętność ręcznego przeprowadzania rachunków ma już
mniejsze znaczenie. Nie chciałbym teraz uzasadniać potrzeby uczenia o liczbach pierwszych.
Chciałbym raczej zwrócić uwagę, że przyszli informatycy powinni znać pojęcie liczby
pierwszej i byłoby bardzo dobrze, gdyby zetknęli się z nim dosyć wcześnie.
Liczby pierwsze są dzisiaj potrzebne do zrozumienia wielu zagadnień o dużym znaczeniu
praktycznym. Są m.in. powszechnie wykorzystywane w algorytmach pozwalających na
szyfrowanie informacji, między innymi takich, od których zależy bezpieczeństwo
internetowej bankowości. Co więcej, nie jest ostatecznie rozstrzygnięte, czy wykorzystywane
metody szyfrowania zapewniają poufność przesyłanych informacji. Dzisiaj stosujemy
metody, o których tylko to przypuszczamy, a twierdzenia o własnościach stosowanych
algorytmów czekają nadal na swoich odkrywców.
Klasyczne testy pierwszości
Informatycy rozważają kilka zadań związanych z liczbami pierwszymi. Po pierwsze, zajmują
się samym problemem pierwszości. Słowo problem powinno tu kojarzyć się z pewnym
pytaniem, w tym przypadku z pytaniem, czy dana liczba jest pierwsza. Zwykle problemy są
utożsamiane ze zbiorami tych danych, dla których odpowiedź jest pozytywna. Tak więc
problem pierwszości bywa utożsamiany ze zbiorem liczb pierwszych (lub przedstawień liczb
pierwszych). Drugim ważnym problemem jest problem złożoności. Odpowiada on zbiorowi
liczb złożonych. Te problemy nie różnią się istotnie, gdy posługujemy się zwykłymi
algorytmami. Wtedy, rozwiązując jeden z nich, jednocześnie rozwiązujemy także drugi.
Mogą zacząć się różnić, gdy zajmiemy się algorytmami niedeterministycznymi lub
wszelkiego rodzaju algorytmami losowymi. Interesujące jest również zadanie znajdowania
dzielnika danej liczby. Różni się od problemu złożoności. Aby je rozwiązać nie wystarczy
ustalić, czy dana liczba jest złożona. Trzeba także wskazać jeden z właściwych dzielników tej
liczby lub stwierdzić, że taki dzielnik nie istnieje. Algorytmy znajdowania dzielnika
pozwalają rozwiązać niewielkim dodatkowym kosztem zadanie faktoryzacji, czyli
znajdowania przedstawienia danej liczby w postaci iloczynu liczb pierwszych.
Naturalne algorytmy badające, czy dana liczba jest pierwsza, są wykładnicze. Łatwo się o tym
przekonać dla najprostszego algorytmu, wynikającego z definicji liczby pierwszej i
sprawdzającego podzielność się przez wszystkie liczby mniejsze. Jeżeli dodatnia liczba
naturalna ma przedstawienie dziesiętne złożone z n cyfr, to jest równa przynajmniej 10n-1 i
badanie, czy jest to liczba pierwsza, wymaga – zgodnie z najpopularniejszą definicją –
wykonania 10n-1-2 dzieleń. Liczba dzieleń wykonywanych podczas takiego sprawdzania
pierwszości jest więc wykładnicza w stosunku do długości przedstawienia badanej liczby,
czyli rozmiaru liczby. Wiadomo, że nie trzeba wykonywać wszystkich dzieleń, ale po
zoptymalizowaniu algorytm i tak pozostanie wykładniczy. Nietrudno też się przekonać, że
algorytm ten wykorzystuje pamięć zaledwie kilka razy większą od potrzebnej do zapisania
danej liczby.
Sito Eratostenesa, opisane w artykule Jana Ulmana, jest jeszcze gorszym algorytmem. Nie
tylko wykonuje wykładniczą liczbę operacji, ale również korzysta z wykładniczej pamięci.
Innym algorytmem badającym pierwszość, dość prostym do zaprogramowania, jest tzw. test
Wilsona. Polega on na obliczaniu reszty z dzielenia (m-1)! przez m. Znając tę resztę bez trudu
można odpowiedzieć na pytanie, czy liczba m jest pierwsza. Dla złożonych liczb m > 4 ta
reszta jest równa 0. Jeżeli zaś m jest liczbą pierwszą, to czynniki iloczynu
1  2  3   (m  2)  (m  1) można grupować w pary złożone z liczb a i b takich, że ab
przystaje do 1 modulo m (dla każdej dodatniej liczby a<m taka liczba b<m istnieje, ponieważ
a jest względnie pierwsze z m, a największy wspólny dzielnik a i m (czyli 1) można
przedstawić w postaci 1 = ab+mn). Podczas liczenia reszty z dzielenia tego iloczynu, po
pogrupowaniu, większość czynników powinna się więc uprościć. W dwóch przypadkach
jednak liczby a nie ma z czym grupować, gdyż a równa się b. Tak jest dla a=1 oraz a=m-1.
Okazuje się więc, że dla każdej liczby pierwszej m liczba (m-1)! przystaje do m-1 (albo do -1)
modulo m.
Nietrudno zauważyć, że test Wilsona też jest algorytmem wykładniczym. Dla liczb o n
cyfrowym przedstawieniu wymaga obliczenia iloczynu 10n-1-2 czynników.
Dla matematyków złożoność obliczeniowa testów nie była pierwszoplanowym zagadnieniem.
Teoria złożoności obliczeniowej zaczęła się rozwijać dopiero około 1960 roku, a informatycy
dość długo nie potrafili powiedzieć niczego interesującego o testowaniu pierwszości. Dopiero
w 1975 roku Vaughan Robert Pratt pokazał, że problem pierwszości należy do klasy NP.
Klasa NP
Symbolem NP oznaczamy klasę problemów rozwiązywanych w sposób niedeterministyczny
w czasie wielomianowym. Aby przybliżyć to pojęcie, posłużymy się problemem, czy dana
liczba jest złożona (czyli problemem złożoności). Najprostszy algorytm rozwiązujący ten
problem przegląda wszystkie liczby mniejsze od danej liczby m i szuka dzielnika. Dzielnika
można jednak szukać na wiele sposobów. Na przykład, można go szukać badając liczby od
najmniejszej do największej
d:= 2; while (d nie_dzieli m) do d:=d+1;
if d<>m then write(’Dana liczba jest złożona.’)
albo odwrotnie, przeglądając liczby od największej do najmniejszej, zgodnie z algorytmem
d:= m-1; while (d nie_dzieli m) do d:=d-1;
if d<>1 then write(’Dana liczba jest złożona.’)
Przypuśćmy, że liczba m jest parzysta. Te dwa algorytmy, mimo że są bardzo podobne, różnią
się istotnie. Pierwszy zakończy pracę po jednorazowym sprawdzeniu podzielności. Drugi –
najpierw będzie testować bez powodzenia wszystkie liczby między m-1 i m/2+1. Zanim
znajdzie dzielnik wykona wykładniczo wiele testów podzielności. Mając więc trochę
szczęścia, możemy błyskawicznie sprawdzić, czy dana liczba jest złożona. Pechowcy, którzy
źle wybrali sposób szukania dzielnika, długo będą czekać na wynik obliczeń. Zdarza się więc,
że badanie złożoności liczby trwa bardzo długo, ale można też mieć nadzieję, że dobierając
odpowiednio algorytm obliczenia da się przeprowadzić krótkim czasie.
Informatycy – mówiąc o takich algorytmach – dzielnik nazywają ,,certyfikatem złożoności’’,
czyli informacją zaświadczającą o złożoności danej liczby.
Wszystkie problemy z klasy NP są podobne do problemu, czy dana liczba jest złożona. Ich
rozwiązanie polega na przeszukaniu dość dużego zbioru, o wykładniczej w stosunku do
rozmiaru danych liczności, w poszukiwaniu tzw. certyfikatu. Jeżeli certyfikat zostanie
znaleziony, to zapoznanie się z nim i sprawdzenie jego poprawności powinno być łatwe, czyli
możliwe do wykonania w czasie wielomianowym.
Formalna definicja klasy NP wymaga przypomnienia pojęcia rozmiaru. Dla liczby naturalnej
m rozmiar r(m) to liczba znaków potrzebna do zapisania przedstawienia tej liczby. Z
dokładnością do stałego czynnika i w przybliżeniu jest to log2m. Informatycy pojęcie
rozmiaru uogólniają na dowolne informacje.
Problem A należy do klasy NP, jeżeli istnieje wielomian w(x) i wielomianowy1 problem B
taki, że
m  A  k r k   wr m  m, k  B.
Zwykły, znany wszystkim algorytm dzielenia liczb, a także oparty o ten algorytm test
podzielności, są wielomianowe. Dzielnik liczby, czyli certyfikat złożoności, ma rozmiar nie
przekraczający rozmiaru tej liczby. Zgodnie z podaną definicją, problem złożoności należy do
klasy NP. Natomiast zadanie znalezienia dzielnika nie należy do klasy NP z przyczyn
formalnych. Zadanie to nie jest problemem, rozwiązując je oczekujemy bardziej
skomplikowanej informacji niż tak lub nie.
Użycie kwantyfikatora egzystencjalnego w definicji NP powoduje, że trudno sobie wyobrazić
dowód zamkniętości klasy NP ze względu na dopełnienie (negację). Tym niemniej
dopełnienie problemu złożoności, czyli problem pierwszości – jak to zauważył Pratt – także
należy do klasy NP.
Pytanie, czy P=NP, i badanie złożoności liczby
Jednym z głównych otwartych problemów informatyki jest pytanie, czy klasa problemów
wielomianowych P jest równa klasie NP. Oczywiście, problemy wielomianowe należą do
klasy NP. Aby więc odpowiedzieć na to pytanie pozytywnie, należałoby wykazać, że każde
zadanie z klasy NP można rozwiązać za pomocą algorytmu wielomianowego. Mówiąc
intuicyjnie, aby dowieść, że P=NP, wystarczy wymyślić taką metodę przeszukiwania danych,
aby zadania dające się szybko rozwiązać przy odrobinie szczęścia mogli sprawnie
rozwiązywać także najwięksi pechowcy. Informatycy wiedzą, że w tym celu nie trzeba badać
wszystkich zadań. Wystarczy za pomocą algorytmu wielomianowego rozwiązać jeden,
dostatecznie trudny problem z klasy NP. Większość informatyków jest jednak przekonana, że
klasy P i NP są różne.
1
Być może przypomnienia wymaga też pojęcie problemu wielomianowego. Tak nazywamy problem, który
można rozwiązać za pomocą algorytmu wielomianowego, a więc wykonującego dla pewnego wielomianu w i
dla każdej z danych rozmiaru n najwyżej w(n) czynności elementarnych. Pojęcie czynności elementarnej jest
dokładnie definiowane, ale może być rozumiane intuicyjnie jako bardzo prosta czynność wykonywana podczas
realizacji algorytmu. Problem B w przytoczonej definicji NP wymaga pary liczb jako danej. Rozmiar takiej pary
to suma rozmiaru jej współrzędnych.
Spróbujmy znowu zająć się naszym przykładem: problemem złożoności. Aby pokazać, że jest
to problem wielomianowy można spróbować opracować metodę, która pozwoli znajdować
wśród liczb < m dzielnik liczby m i będzie wykonywać wielomianową w porównaniu z log2 m
liczbę elementarnych czynności. Gdyby taką metodą udało się znaleźć – i co najważniejsze –
gdyby była ona dostatecznie ogólna i dawałaby się zastosować także w innych przypadkach,
to klasy P i NP byłyby równe. Jest to mało prawdopodobne i chyba w ten sposób problemu
złożoności nie da się rozwiązać.
Znalezienie szczególnej, wielomianowej metody służącej do szukania dzielnika mogłoby nie
wystarczyć do wykazania, że P=NP. Pytanie o istnienie takiej metody też nie jest jeszcze
rozwiązane. Także w tym przypadku informatycy są przekonani, że taka metoda nie istnieje.
Jest to bardzo ważne pytanie, gdyż od odpowiedzi na nie zależy bezpieczeństwo danych
przesyłanych za pomocą sieci komputerowych.
Zanim poznamy odpowiedź na pytanie, czy problem złożoności jest wielomianowy, wróćmy
na chwilę do historycznie wcześniejszych badań Pratta. Przy okazji jeszcze raz zobaczymy,
jak można wykazać, że jakiś problem należy do klasy NP.
Twierdzenie Pratta
W dowodzie swojego twierdzenia Pratt korzystał z tzw. testu Lucasa. Jego poprawność
wynika łatwo z istnienia pierwiastków pierwotnych. Aby zaś wyjaśnić pojęcie pierwiastków
pierwotnych musimy przypomnieć sobie małe
Twierdzenie Fermata. Jeżeli m jest liczbą pierwszą, to dla dowolnej dodatniej liczby a < m
liczba am-1 przystaje do 1 modulo m.
Fakt ten można również wyrazić nieco inaczej: w ciele Zm reszt z dzielenia przez liczbę
pierwszą m, z dodawaniem i mnożeniem modulo m, wszystkie niezerowe elementy są
pierwiastkami z jedności stopnia m-1. Wśród m-1 pierwiastków z jedności stopnia m-1 jest
też pierwiastek pierwotny, czyli taki, który nie jest jednocześnie pierwiastkiem stopnia
mniejszego niż m-1. Czasem nazywa się go krótko pierwiastkiem pierwotnym modulo m (lub
dla modułu m). Zachodzi też
Twierdzenie 2. Liczba naturalna m jest pierwsza wtedy i tylko wtedy, gdy w Zm istnieje
pierwiastek pierwotny modulo m.
Tak więc istnienie pierwiastków pierwotnych nie tylko wynika z pierwszości liczby, ale też
charakteryzuje liczby pierwsze. Fakt ten jest wykorzystywany w teście Lucasa, zgodnie z
którym po prostu szukamy pierwiastka pierwotnego modulo dana liczba. Natomiast badanie,
czy a jest pierwiastkiem pierwotnym modulo m, polega – zgodnie z tym testem – na
sprawdzeniu
1. czy am-1 przystaje do 1 modulo m oraz
2. czy a(m-1)/q nie przystaje do 1 modulo m dla każdej liczby pierwszej q dzielącej m-1.
Test Lucasa sugeruje, że certyfikatem pierwszości liczby m może być informacja złożona z
pierwiastka pierwotnego a modulo m i wszystkich dzielników pierwszych liczby m-1.
Rzeczywiście, mając a i dzielniki pierwsze m-1 łatwo sprawdzić większość warunków z testu
Lucasa. Nie jest to jednak dobre rozwiązanie, gdyż sprawdzenie poprawności certyfikatu
powinno obejmować także badanie pierwszości wymienionych dzielników. Liczbę a wraz z
wszystkimi dzielnikami pierwszymi d1,…,dt liczby m-1 będziemy nazywać niepełnym
certyfikatem i będziemy zapisywać jako (a,d1,…,dt). Pratt dodatkowo zauważył, że jeżeli
niepełny certyfikat pierwszości uzupełnimy o niepełne certyfikaty pierwszości wymienionych
w nim liczb pierwszych, a także o niepełne certyfikaty pierwszości liczb pierwszych w
dołączonych certyfikatach itd., to otrzymamy informację, której rozmiar jest tylko
kwadratowy w porównaniu z rozmiarem danej liczby. Otrzymana w ten sposób informacja nie
jest duża, może więc być certyfikatem pierwszości liczby m.
Na przykład certyfikatem pierwszości liczby 23 może być informacja
(5,2,11(2,2,5(3,2))),
którą powinniśmy rozumieć jako stwierdzenie, że liczba 23 jest pierwsza, ponieważ 5 jest
pierwiastkiem pierwotnym modulo 23, a 22 dzieli się tylko przez 2 (które jest oczywiście
liczbą pierwszą i stwierdzenie tego faktu nie wymaga już żadnego certyfikatu) oraz przez 11.
Liczba 11 jest pierwsza, gdyż 2 jest świadczącym o tym pierwiastkiem pierwotnym, a 10
dzieli się tylko przez dwie liczby pierwsze 2 i 5. W końcu 5 jest liczbą pierwszą, gdyż 3 jest
pierwiastkiem pierwotnym modulo 5, a 4 dzieli się tylko przez liczbę pierwszą 2. Mając tak
rozumiany certyfikat bez trudu, zgodnie z testem Lucasa, przeprowadzamy obliczenia
dowodzące kolejno pierwszości liczb 5, 11 i w końcu liczby 23. W ogólnym przypadku
potrzebne do tego obliczenia są wielomianowe.
Współczesne testy pierwszości
Po ogłoszeniu wyniku Pratta było wiadomo, że zarówno problem pierwszości, jaki i jego
dopełnienie, czyli problem złożoności, są w klasie NP. Zdaniem wielu badaczy wskazywało
to na istnienie wielomianowego algorytmu badającego pierwszość. Ważnym argumentem był
też test pierwszości podany przez Gary Millera w 1976 roku. Miller przedstawił także dowód
wielomianowości swojego testu, przeprowadzony jednak przy założeniu rozszerzonej
hipotezy Reimanna, której prawdziwość nie jest rozstrzygnięta. W tej sytuacji trudno się
dziwić, że matematycy i informatycy rozpoczęli poszukiwania efektywnych algorytmów. W
1983 roku Leonard Adleman, Carl Pomerance i Robert Rumeley podali pierwszy
deterministyczny test pierwszości, który nie jest wykładniczy2, ale też nie jest jeszcze
wielomianowy. Opracowano również wiele innych testów, często z elementami losowymi.
Dzisiaj wynik Pratta ma już tylko historyczne znaczenie. W 2002 roku matematyk hinduski
Manindra Agraval oraz jego uczniowie Neeraj Kayal i Nitin Saxena podali deterministyczny i
wielomianowy test pierwszości. Jak to bywa często w teorii liczb, mimo że długo szukano
takiego testu, dowód jego poprawności nie jest trudny. Może go zrozumieć student
matematyki po wysłuchaniu kursowych wykładów z teorii ciał skończonych. Test jest oparty
o następującą charakteryzację liczb pierwszych:
Twierdzenie 3. Przyjmijmy, że liczby naturalne m i a<m są względnie pierwsze. Liczba m
jest pierwsza wtedy i tylko wtedy, gdy wielomian (x-a)m o współczynnikach z pierścienia
reszt modulo m jest równy wielomianowi xm-a.
2
Taka uwaga wymaga od autora dużej wiedzy historycznej. Przytaczam ją na podstawie pracy PRIMES is in P
autorstwa Manindra Agravala i jego studentów, relacjonowanej w dalszej części artykułu. Z tej pracy pochodzi
także kilka innych przytoczonych przeze mnie szczegółów historycznych.
Przypuszczam, że wielu Czytelników Matematyki jest w stanie samodzielnie zweryfikować
przytoczone twierdzenie3. Więcej kłopotów autorom testu sprawiła jego wielomianowość.
Pokazali ostatecznie, że dla liczb o rozmiarze n ich algorytm wykonuje najwyżej c  n12
operacji dla pewnej stałej c, a jeżeli są prawdziwe pewne hipotezy, to realizacja algorytmu
może wymagać wykonania tylko c  n 6 operacji.
Z pracy Agravala wynika także, że problem złożoności jest wielomianowy. Nie wiem, czy
test Agravala ma znaczenie praktyczne. Zdarza się, że algorytmy wielomianowe gorzej
spisują się dla danych mających znaczenie praktyczne od algorytmów wykładniczych.
Deterministyczne algorytmy mają też dodatkową konkurencję ze strony algorytmów
probabilistycznych.
Posługiwanie się algorytmami probabilistycznymi wymaga istotnej, wręcz rewolucyjnej
zmiany sposobu myślenia. Rozwiązując zadanie zwykle chcemy uzyskać jednoznaczną
odpowiedź: tak lub nie. W przypadku algorytmów probabilistycznych otrzymujemy też
informację: najprawdopodobniej tak. Takie algorytmy często okazują się bardzo efektywne,
ale ceną jest możliwość popełnienia błędu. Są znane także dla interesującego nas zadania.
Jeden z najwcześniejszych i najbardziej znanych probabilistycznych testów, rozwiązujący
problem pierwszości, o olbrzymim znaczeniu praktycznym został zaproponowany przez
Michaela Rabina w 1980 roku.
Sylwetka Michaela Rabina
Michael Oser Rabin jest głównym bohaterem tego artykułu i jednym z najwybitniejszych
współczesnych informatyków. Urodził się w 1931 roku we Wrocławiu. Przed drugą wojną
światową znalazł się w Palestynie. W 1953 roku ukończył studia matematyczne na
Uniwersytecie Hebrajskim w Jerozolimie. Odgrywa ciągle istotną rolę w rozwoju
informatyki.
Brał udział w tworzeniu teorii złożoności obliczeniowej. Był pierwszym uczonym, który
zwracał uwagę na znaczenie niedeterminizmu i odegrał pewną rolę w ukształtowaniu takiego
pojęcia, jak klasa NP. Został za to uhonorowany w 1976 roku razem z Dana Scottem nagrodą
Turinga, która dla informatyków jest odpowiednikiem medalu Fieldsa przyznawanego za
największe osiągnięcia matematyczne lub nagrody Nobla za wyniki z fizyki, chemii i innych
dziedzin.
Szczególnie znaczące osiągnięcia ma w kryptografii. Opracował system szyfrujący, pierwszy
tego rodzaju, o którym wiadomo, jak trudno rozszyfrowywać tworzone przez niego
komunikaty. W tym systemie rozszyfrowywanie komunikatów jest tak samo trudne, jak
rozkładanie liczby na czynniki pierwsze. W praktyce stosowany jest system szyfrujący RSA
oparty o metodę zaproponowaną przez Ronalda Rivesta, Adi Shamira i Leonarda Adlemana,
którego komunikaty też można odczytywać mając efektywny algorytm rozwiązujący zadanie
faktoryzacji. Jednak nie wiadomo, czy nie można ich odczytywać jeszcze w inny sposób.
Jest doktorem honoris causa wielu znaczących uniwersytetów. Z inicjatywy prof. Leszka
Pacholskiego, rektora Uniwersytetu Wrocławskiego i długoletniego dyrektora Instytutu
3
Jako wskazówkę przytoczę następujący fakt: jeżeli q jest liczbą występującą k krotnie w rozkładzie liczby m na
iloczyn liczb pierwszych, to liczba qk nie dzieli
m
  .
q
Informatyki, także Senat Uniwersytetu Wrocławskiego podjął uchwałę o nadaniu Michaelowi
Rabinowi doktoratu honorowego. Uroczystość promocji honorowej odbyła się13 lipca 2007
roku w Auli Leopoldyńskiej Uniwersytetu Wrocławskiego w obecności uczestników
międzynarodowych konferencji informatycznych: 34th Intenational Colloquium on Automata,
Languages and Programming oraz 22th Symposium on Logic in Computer Science, a także
matematycznej konferencji Logic Colloquium. Podczas uroczystości w auli byli obecni
uczeni z całego świata, w tym Dana Scott, aktualny przewodniczący komitetu nagrody
Turinga i współautor nagrodzonej pracy o niedeterminizmie i automatach skończonych, a
także ambasador Izraela i najbliższa rodzina Michaela Rabina.
Szukając informacji o wynikach Michaela Rabina przejrzałem ksiązki z informatyki
teoretycznej, które mam w domu. We wszystkich były cytowane jego prace. W większości o
osiągnięciach Profesora można było czytać w kilku lub nawet w kilkunastu miejscach. Teraz
sygnalizowałem tylko osiągnięcia związane z treścią artykułu. Interesuje nas jeszcze
probabilistyczny test pierwszości.
Probabilistyczny test Rabina
Aby lepiej zrozumieć test Rabina zacznijmy od testu Fermata, stosowanego od dawna przez
matematyków, ale uważanego za narzędzie pomocnicze. Jest on oparty o małe twierdzenie
Fermata.
W twierdzeniu Fermata prawdziwa jest nie tylko podana implikacja, ale także implikacja
odwrotna. Twierdzenie uzupełnione o tę implikację stanie się charakteryzacją liczb
pierwszych i może być podstawą algorytmu testującego pierwszość. Algorytm ten powinien
badać wszystkie liczby mniejsze niż m i będzie wykładniczy. Dla każdej liczby a < m
sprawdzi, czy am-1 przystaje do 1 modulo m.
Jeżeli przeprowadzenie obliczeń dla wszystkich liczb mniejszych od m okaże się zbyt
żmudne, to zawsze można przeprowadzić je dla kilku wybranych wartości a i spróbować stąd
wyciągnąć wnioski. Jeżeli dla chociaż jednej liczby okaże się, ze am-1 nie przystaje do 1
modulo m, to liczba m będzie złożona. Jeżeli we wszystkich sprawdzonych przypadkach am-1
przystaje do 1 modulo m, to jest jakaś szansa, że m jest liczbą pierwszą. Informatycy uznali,
że tę szansę należy zbadać. W tym celu rozważymy następujący algorytm – test Fermata: dla
danej liczby m
1. wylosuj dodatnią liczbę a < m i sprawdź, czy am-1 przystaje do 1 modulo m,
2. jeżeli tak jest, to przekaż, że m jest prawdopodobnie liczbą pierwszą, a w przeciwnym
razie – stwierdź, że m jest liczbą złożoną.
Podany algorytm udziela odpowiedzi, która zależy od wylosowanej liczby. Nie myli się
nigdy, gdy stwierdza, że dana liczba jest złożona, i może popełnić błąd, który polega na
przekazaniu o liczbie złożonej informacji, że jest prawdopodobnie pierwsza.
Od algorytmu probabilistycznego, takiego jak przedstawiony, oczekujemy, że niezależnie od
danej robi błąd z prawdopodobieństwem nie przekraczającym pewnej stałej c<1. Algorytmy
spełniające ten warunek określamy mianem Monte Carlo.
Mając taki algorytm, można konstruować efektywne algorytmy probabilistyczne. Wystarczy
go dla danej liczby m wielokrotnie powtarzać. Prawdopodobieństwo popełnienia błędu
podczas k kolejnych i niezależnych powtórzeń algorytmu Monte Carlo nie przekracza liczby
ck. Dobierając odpowiednio liczbę powtórzeń możemy uzyskać algorytm popełniający błąd z
zadanym prawdopodobieństwem, także niemal równym zero.
Przypuśćmy, że test Fermata uruchamiamy z liczbą złożoną m, a więc w sytuacji, gdy może
popełnić błąd. Jeżeli zostanie wylosowana liczba a, która ma wspólny dzielnik z m, to
otrzymamy poprawną odpowiedź. Gdyby bowiem algorytm przekazał błędną odpowiedź, to
potęga am-1 przystawałaby do 1 modulo m i wspólny dzielnik liczb a i m dzieliłby także 1.
Błędna odpowiedź może się pojawić wyłącznie po wylosowaniu liczby względnie pierwszej
z m.
Będziemy teraz przez chwilę rozważać liczbę m będącą iloczynem4 trzech różnych liczb
pierwszych p, q i r. Nietrudno przekonać się, że jest (p-1)(q-1)(r-1) liczb mniejszych od m i
względnie pierwszych z m. Wobec tego prawdopodobieństwo popełnienia błędu przez nasz
( p  1)(q  1)(r  1)
algorytm jest nie większe niż
. Zauważmy, że jeżeli będziemy zwiększać
pqr  1
liczby p, q i r, to znalezione oszacowanie będzie zbliżać się do 1.
Co gorsze, w niektórych przypadkach prawdopodobieństwo popełnienia błędu jest takie, jak
znalezione oszacowanie. Są liczby złożone m, dla których teza małego twierdzenia Fermata
jest spełniona dla wszelkich liczb względnie pierwszych z m i podany algorytm zawsze po
wylosowaniu liczby względnie pierwszej z m udzieli błędnej odpowiedzi. Nazywamy je
liczbami Carmichaela, a najmniejszą taką liczbą jest 561. Wskazuje to, że test Fermata nie
jest algorytmem Monte Carlo.
Aby otrzymać dobrą charakteryzację liczb pierwszych, pozwalającą na skonstruowanie
algorytmu Monte Carlo, tezę twierdzenia Fermata trzeba uzupełnić o dodatkowe informacje o
liczbach pierwszych. Gary Miller w swoim algorytmie korzystał z następującego faktu:
Twierdzenie 4. Jeżeli m jest liczbą pierwszą, to każda liczba x, której kwadrat przystaje do 1,
przystaje modulo m albo do 1, albo do -1.
Jest to znany fakt. Reszty z dzielenia przez liczbę pierwszą tworzą ciało, a w każdym ciele
równanie x2=1 ma dwa pierwiastki: 1 i -1.
Teza twierdzenia 4 zachodzi dla wielu liczb m, nie tylko dla pierwszych. Nie zachodzi jednak
dla liczb, które można przedstawić w postaci iloczynu pq względnie pierwszych liczb p i q
większych od 2. Tezę tego twierdzenia poza liczbami pierwszymi spełniają więc najwyżej
liczby parzyste oraz potęgi liczb pierwszych. Te dwa rodzaje liczb nie są jednak liczbami
Carmichaela. Spostrzeżenie to pozwala dowieść
Twierdzenie 5. Jeżeli
1. dla każdej dodatniej liczby a < m i względnie pierwszej z m potęga am-1 przystaje do 1
modulo m oraz
2. x2 przystaje do 1 modulo m tylko dla liczb x przystających do 1 i do -1 modulo m,
to m jest liczbą pierwszą.
4
Liczby Carmichaela, które w tej chwili zaczynamy analizować, są iloczynami przynajmniej trzech różnych
liczb pierwszych. O niektórych własności tych liczb dowiemy z dalszych rozważań.
Twierdzenie 5 dla wygody połączymy z twierdzeniem Fermata i twierdzeniem 4 oraz
sformułujemy używając odpowiedniejszej terminologii.
Liczbę m najpierw przedstawmy w postaci m=2kn+1 dla pewnej nieparzystej liczby n. O
liczbie a będziemy mówić, że świadczy o pierwszości m, jeżeli albo an przystaje do 1 modulo
i
m, albo a 2 n przystaje do -1 modulo m dla pewnej liczby naturalnej i  k . Wprowadzone
pojęcie pozwala w następujący sposób podsumować przeprowadzone rozumowania.
Twierdzenie 6. Liczba m jest pierwsza wtedy i tylko wtedy, gdy każda dodatnia liczba
a  m świadczy o pierwszości m.
Twierdzenie 6 jest podstawą algorytmu Gary Millera. Michael Rabin, propagujący przy
każdej okazji algorytmy probabilistyczne, zaproponował także w oparciu o nie następujący
test pierwszości liczby m:
1. wylosuj dodatnią liczbę naturalną a < m i sprawdź, czy a świadczy o pierwszości m,
2. jeżeli świadczy, to przekaż, że m jest prawdopodobnie liczbą pierwszą, w przeciwnym
razie przekaż, że m jest liczbą złożoną.
O teście Rabina stosunkowo łatwo dowodzi się, że popełnia błąd najwyżej z
prawdopodobieństwem ½. Aby się o tym przekonać, musimy przeanalizować działanie tego
testu dla złożonych liczb m.


Niech G  x  m : x m1  1 mod m oraz Z m  x  m : x jest wzglednie pierwsze z m.
Oczywiście G jest podzbiorem Z m . Oba te zbiory są zamknięte ze względu na mnożenie
modulo m i są grupami z tym działaniem. Tak więc, zgodnie z twierdzeniem Lagrange’a,
liczba elementów G dzieli rząd Z m . Nietrudno też zauważyć, że zarówno w przypadku testu
Fermata, jak i testu Rabina, wszystkie liczby a generujące błędne odpowiedzi należą do G.
Jeżeli m nie jest liczbą Carmichaela, to G  Z m i liczba elementów Z m jest przynajmniej dwa
razy większa od liczby elementów G. Poprawne odpowiedzi otrzymamy więc po
wylosowaniu liczby a, która nie jest względnie pierwsza z m i dla przynajmniej połowy
pozostałych liczb. Tak więc prawdopodobieństwo popełnienia błędu w tym przypadku jest
1
 .
2
Jeżeli m jest liczbą Carmichaela, to co prawda G  Z m , ale sytuacja jest podobna. Nieco
subtelniejsze, analogiczne rozumowanie pozwala oszacować prawdopodobieństwo błędu.
Liczba m jest wtedy nieparzysta i można ją przedstawić w postaci 2k+1n+1 dla pewnej liczby


nieparzystej n. Jeżeli teraz przyjmiemy, że Gi  x  m : x 2 n  1 mod m , to będziemy mogli
inaczej zapisać definicję G. Oczywiście dla i=k+1 zachodzi równość Gi  G . Może się
jednak zdarzyć, ze równość ta jest też prawdziwa dla innych i. Przyjmijmy, że l jest
najmniejszą liczbą taką, że Gl  G . Ponieważ m-1 nie należy do G0, więc l > 0.
i

l 1

Liczby a powodujące błędy testu Rabina należą do zbioru G'  x  m : x 2 n  1 mod m .
Zbiór ten też jest zamknięty ze względu na mnożenie modulo m, a więc jest podgrupą Z m .
Można dowieść, że jest właściwą podgrupą. Dalsze szacowanie prawdopodobieństwa błędu
przebiega tak, jak w poprzednim przypadku. A więc zarówno dla liczb Carmichaela, jak i
pozostałych, prawdopodobieństwo popełnienia błędu przez test Rabina nie przekracza ½. Test
Rabina jest więc probabilistycznym algorytmem Monte Carlo i pozwala konstruować
efektywne algorytmy, które można wykorzystać zarówno do badania złożoności liczby, jak i
sprawdzania, czy dana liczba jest pierwsza.
Michael Rabin zauważył jeszcze, że jeżeli m jest liczbą złożoną, to nie połowa jak
pokazaliśmy, a najwyżej jedna czwarta liczb mniejszych niż m świadczy o pierwszości m.
Test Rabina popełnia więc błąd z prawdopodobieństwem nie przekraczającym ¼. Jeżeli
będziemy go niezależnie powtarzać, a po t krotnym powtórzeniu popełni już błąd z
prawdopodobieństwem nie przekraczającym 1/4t.
Jest to bardzo prosty algorytm. Od studenta pierwszego roku informatyki, uczącego się
programowania, oczekiwałbym, że w ciągu kilku tygodni przygotuje oparty o naturalne
algorytmy5 program realizujący test Rabina i pozwalający eksperymentować z badaniem
pierwszości liczb o długich przedstawieniach. Sądzę, że taki projekt mogłaby zrealizować pod
kierunkiem nauczyciela także grupa uczniów uczestniczących na przykład w zajęciach
pozalekcyjnych z informatyki.
Uzupełnienia.
Dla Czytelników zainteresowanych bardziej szczegółowymi dowodami przedstawię na koniec
rozumowania świadczące o prawdziwości kilku faktów użytych w artykule.
Żadna liczba parzysta m > 2 nie jest liczbą Carmichaela. Aby się o tym przekonać, wystarczy
zauważyć, że (m-1)m-1 przystaje do -1 modulo m. Liczbę przystającą do -1 podnosimy
przecież do nieparzystej potęgi.
Trudniej uzasadnić, że potęga m=pk liczby pierwszej p nie jest liczbą Carmichaela. Tak jest,
gdyż dla k > 1 mamy
p
 p
 p
( p k 1  1) p     p ( k 1)i    p k 1  1  1 mod p k .
i 2  i 
1
Gdyby m było liczbą Carmichaela, to także
( p k 1  1) p
k
1
 1 mod p k
i ze względnej pierwszości wykładników w powyższych wzorach otrzymalibyśmy, że
p k 1  1 przystaje do 1 modulo pk. To oznaczałoby, że pk dzieli pk-1, co nie jest możliwe.
Jeżeli p i q są względnie pierwszymi liczbami większymi od 2 i m=pq, to istnieją
przynajmniej trzy dodatnie liczby x < m, których kwadraty przystają do 1 modulo m. Zawsze
do 1 przystają modulo m kwadraty liczb 1 oraz m-1.
Kolejną taką liczbę można skonstruować w następujący sposób: najpierw przedstawiamy
największy wspólny dzielnik p i q (czyli 1) w postaci 1=ap+bq i bierzemy liczbę x przystającą
do (p-1)bq+ap modulo m. Liczba x przystaje do -1 modulo p oraz do 1 modulo q. Stąd x2
5
Trzeba pamiętać, że algorytm potęgowania oparty o zwykłą definicję jest wykładniczy. Potęgę można jednak
obliczać za pomocą łatwego do zrozumienia i dość naturalnego wielomianowego algorytmu.
przystaje do 1 modulo pq. Liczba x nie przystaje jednak do 1 modulo pq. W przeciwnym
razie, przystawałaby modulo p jednocześnie do 1 i do -1, a to jest możliwe wyłącznie dla p=2.
Analogicznie, analizując przystawanie modulo q, pokazujemy, że x nie przystaje do -1 (ani
m-1) modulo pq.
Nadal niech m będzie iloczynem względnie pierwszych i nieparzystych liczb p i q. Ponieważ
– zgodnie z wcześniejszymi oznaczeniami – Gl-1 jest różne od G, więc dla t  2 l 1 n istnieje
względnie pierwsza z m liczba x taka, że xt nie przystaje do 1 modulo m. Wtedy istnieje też
względnie pierwsza z m liczba y taka, że yt nie przystaje modulo m ani do 1, ani do -1. Liczba
ta nie należy G ' , mimo że należy do G.
Jeżeli xt nie przystaje do 1 modulo m, to także nie przystaje do 1 albo modulo p, albo modulo
q. W obu przypadkach postępujemy analogicznie. Załóżmy więc, że xt nie przystaje do 1
modulo p. Znajdźmy znowu przedstawienie największego wspólnego dzielnika p i q (czyli 1)
w postaci ap+bq i przyjmijmy, że y jest resztą z dzielenia xbq+ap przez m. Liczba y przystaje
do x modulo p oraz do 1 modulo q. Wynika stąd, że jest względnie pierwsza zarówno z p, jak
i z q. Jest więc względnie pierwsza z m. Potęga yt nie przystaje ani do 1, ani do -1 modulo m.
Nie przystaje do 1, ponieważ y przystaje do x modulo p. Gdyby zaś przystawała do -1 modulo
m, to także przystawałaby -1 modulo q. Nie może jednak przystawać modulo m jednocześnie
do 1 i do -1 dla m > 2.
Download