StartAlgorytmyAlgorytmy arytmetyczneTest pierwszości - test Millera-Rabina
Baza Wiedzy
Wersja offline serwisu przeznaczona na urządzenia z systemem Android.

Darowizny
darowiznaWspomóż rozwój serwisu


Nagłówki RSS
Kanał artykuły
Kanał implementacje
Kanał komentarze
Kanał forum


Bookmarki









Sonda
Implementacji w jakim języku programowania poszukujesz?
 
Test pierwszości - test Millera-Rabina
Ocena użytkowników:+++++ / 17
SłabyŚwietny 
Wpisany przez Tomasz Lubiński
czwartek, 26 kwietnia 2007 21:35
Test pierwszości Millera-Rabina to probabilistyczny test umożliwiający sprawdzenie czy dana liczba jest złożona czy prawdopodobnie pierwsza. Metoda, w oparciu o którą powstała to deterministyczny algorytm Millera, którego poprawność zależy od nieudowodnionej uogólnionej hipotezy Riemanna. Michael O. Rabin zmodyfikował ten algorytm do postaci testu probablistycznego i dowiódł jego poprawności w tej postaci. Algorytm używany jest do sprawdzania wyłącznie liczb nieparzystych (liczby parzyste - za wyjątkiem dwójki - w sposób oczywisty nie są liczbami pierwszymi). Test Millera-Rabina można zapisać następująco:
k- określa dokładność testu
n - nieparzysta liczba do sprawdzenia

Wylicz s - maksymalną potęgę dwójki dzielącą n-1.
Podstaw d = n/2s
powtórz k razy:
  wylosuj a takie, że 1<a<n
  sprawdź czy ad mod n różne od 1
  jeżeli tak to sprawdz czy ad*2r mod n rozne od n-1 dla wszystkich r, takich że: 0≤r≤s-1
     jeżeli tak to to przerwij test - liczba nie jest pierwsza
jeżeli nie przerwano testu dla żadnej z prób to liczba prawdopodobnie jest pierwsza

Na pierwszy rzut oka trudność sprawiać może obliczenie wartości ab mod n, szczególnie dla dużych wartości b. Szybko i bezproblemowo obliczymy taką wartość używając algorytmu szybkiego potęgowania modularnego lub dużo wolniejszego, ale prostszego algorytmu naiwnego potęgowania modularnego.

Można pokazać że dla dowolnej złożonej nieparzystej liczby naturalnej n co najmniej 3/4 możliwych wartości a jest dobrymi świadkami złożoności tej liczby. Jeśli zatem przeprowadzamy k losowych prób, prawdopodobieństwo że określimy liczbę złożoną jako pierwszą wynosi co najwyżej 4-k.

Przykład:
Sprawdzimy z dokładnością k=3, czy liczba n=13 jest pierwsza.
Najpierw obliczymy maksymalną potęge dwójki dzielącą n-1.
12 mod 2 = 0, 12 mod 4 = 0, 12 mod 8 != 0. Zatem maksymalną potęgą dwójki dzielącą 12 jest 4, czyli 4=2s, s=2.
Obczliymy teraz d = 13/4 = 3 (dzielenie całkowitoliczbowe).
Pierwsza próba a=2.
23 mod 13 = 8, jest różne od 1, zatem przechodzimy do drugiego sprawdzenia.
r = 0, 23 mod 13 = 8.
r = 1, 26 mod 13 = 12.
Dla r = 1, ad*2r mod n równe jest n-1, zatem kontuujemy test.
Druga próba a=6.
63 mod 13 = 8, jest różne od 1, zatem przechodzimy do drugiego sprawdzenia.
r = 0, 63 mod 13 = 8.
r = 1, 66 mod 13 = 12.
Dla r = 1, ad*2r mod n równe jest n-1, zatem kontuujemy test.
Trzecia próba a=11.
113 mod 13 = 5, jest różne od 1, zatem przechodzimy do drugiego sprawdzenia.
r = 0, 113 mod 13 = 5.
r = 1, 116mod 13 = 12.
Dla r = 1, ad*2r mod n równe jest n-1, zatem kontuujemy test.
Wykonaliśmy wszystkie próby, nie stwiedziliśmy, że liczba jest złożona, zatem 13 jest prawdopodobnie liczbą pierwszą.

Sprawdzimy z dokładnością k=3, czy liczba n=9 jest pierwsza.
Najpierw obliczymy maksymalną potęge dwójki dzielącą n-1.
8 mod 2 = 0, 8 mod 4 = 0, 8 mod 8 = 0, 8 mod 16 != 0. Zatem maksymalną potęgą dwójki dzielącą 8 jest 8, czyli 8=2s, s=3.
Obliczymy d = 8/8 = 1.
Pierwsza próba a=2.
21 mod 9 = 2, jest różne od 1, zatem przechodzimy do drugiego sprawdzenia.
r = 0, 21 mod 9 = 2.
r = 1, 22 mod 9 = 4.
r = 2, 24 mod 9 = 7.
Wyniki drugiego sprawdzenia są różne od n-1 dla wszystkich r, zatem liczba 9 nie jest liczbą pierwszą, możemy przerwać test.



Autor Język programowania Komentarz Otwórz Pobierz Ocena
Tomasz Lubiński Ada
Implementacja w Ada
Implementacja w Ada
++++- / 2
Tomasz Lubiński C# MS Visual Studio .net
Implementacja w C#
Implementacja w C#
++++- / 3
Tomasz Lubiński C/C++
Implementacja w C/C++
Implementacja w C/C++
+++-- / 5
Tomasz Lubiński Delphi/Pascal
Implementacja w Delphi/Pascal
Implementacja w Delphi/Pascal
+++-- / 2
Tomasz Lubiński Java
Implementacja w Java
Implementacja w Java
+++-- / 3
 
Dodaj własną implementację tego algorytmu
  • Zaloguj się na stronie
Plik:
Język programowania:
Komentarz:
  By móc dodać implementacje zaloguj się na stronie



Poprawiony: środa, 26 maja 2010 22:28

Dodaj komentarz

Kod antysapmowy
Odśwież