Rabin-Millerův test prvočíselnosti

Transkript

Rabin-Millerův test prvočíselnosti
2010-02-09_3
Rabin-Millerův test prvočíselnosti
Rabin-Millerův test je pravděpodobnostní algoritmus typu Monte Carlo – náhoda použitá v algoritmu
ovlivňuje jak dobu běhu algoritmu, tj. po jak dlouhé době se dobereme výsledku, tak i samotnou
správnost algoritmu, tj. algoritmus může udělat chybu a rozhodnout špatně, ale tyto případy se snaží
minimalizovat. Tento algoritmus má chybu jednostrannou – tj. pokud odpoví číslo složené, víme
určitě, že odpověděl správně, ale pokud naopak odpoví prvočíslo, mohl se splést.
Pro kratší zápis operace modulo, která je zde poměrně častá si zavedeme zkrácený zápis:
zá‫≡ ݉݁ݏ݅݌‬௡ ‫݉ݑݖ݋ݎ‬í݉݁ ‫݊ ݋݈ݑ݀݋݉ ݐݏ݋݊ݒ݋ݎ‬
Tvrzení: Předpokládejme, že n je liché prvočíslo. Nechť ݊ − 1 = 2௥ ∙ ‫ ݏ‬kde ‫ ݏ‬je liché. Dále nechť
1 ≤ ܽ ≤ ݊ − 1. Potom platí ܽ ௦ ≡௡ 1 ܾ݊݁‫ܽ ݋‬ଶ
ೕ௦
≡௡ − 1 ‫݊ ݋ݎ݌‬ě݆ܽ݇é 0 ≤ ݆ ≤ ‫ ݎ‬− 1.
ೕ
Poznámka: Pokud testování pomocí tohoto tvrzení selže, tj. ܽ ௦ ≢௡ 1 & ܽଶ ௦ ≢௡ − 1 ∀݆ ∶ 0 ≤ ݆ ≤ ‫ ݎ‬−
1, víme, že ݊ je složené a ܽ je toho svědkem.
Použití tohoto tvrzení vlastně jen spočívá v modulárním mocnění čísla ܽ௖ , tedy časová složitost závisí
jen na tom, jak rychle zvládneme umocňovat.
Co je potřeba pro důkaz tvrzení:
ࢇ) ࡹࢇ࢒á ࡲࢋ࢘࢓ࢇ࢚࢕࢜ࢇ ࢜ě࢚ࢇ: ܲ‫ܽ݇ ݋ݎ‬ž݀é ‫݋ݒݎ݌‬čí‫ܽ݇ ܽ ݌ ݋݈ݏ‬ž݀é ݈ܿ݁é čí‫ݒ݋݇ܽݐ ܽ ݋݈ݏ‬é, ž݁ ‫݀݁݊ ݌‬ě݈í ܽ, ‫ݐ݈ܽ݌‬í
ܽ௣ିଵ ≡ 1 ݉‫݌ ݀݋‬
࢈) ࡼ࢕࢓࢕ࢉ࢔é: ܲ‫݋ݒݎ݌ ݆݁ ݌ ݀ݑ݇݋‬čí‫ ݔ ܽ ݋݈ݏ‬ଶ ≡௣ 1, ‫≡ ݔ ݉݋ݐ݋݌‬௣ 1 ܾ݊݁‫≡ ݔ ݋‬௣ − 1
Pomocné tvrzení si dokážeme:
‫ ݔ‬ଶ ≡௣ 1
‫ ݔ‬ଶ −1 ≡௣ 0
ሺ‫ ݔ‬− 1) ∙ ሺ‫ ݔ‬+ 1) ≡௣ 0
Pokud p nedělí ሺ‫ ݔ‬− 1) ani ሺ‫ ݔ‬+ 1) ale dělí jejich součin, potom x nemůže být prvočíslem, což nás
vede ke sporu. Z tohoto důvodu bude p dělit buď ሺ‫ ݔ‬− 1) nebo ሺ‫ ݔ‬+ 1). Takže platí ‫≡ ݔ‬௣ ± 1.
Postupně počítáme mocniny, začneme s ܽ௡ିଵ pokud nevyjde +1, Fermatův test nám potvrdí
೙షభ
složenost čísla ݊. Pokud vyjde 1 a ݊ − 1 je sudé, tak a na polovinu exponentu, tedy ܽ మ musí být
opět odmocnina z jedničky, ty jsou dvě (dle pomocného tvrzení b) ). Pokud vyjde něco jiného než ±1
pak víme, že ݊ není prvočíslem. Jinak opět pokračujeme, tedy spočítáme ܽ
೙షభ
ర
atd.
ࡰࢋࢌ࢏࢔࢏ࢉࢋ: ܵ‫ݒ‬ě݀݁݇ ܽ ݆݁ čí‫݋݈ݏ‬, ݇‫ݎ݁ݐ‬é ‫݀ݎݒݐ݋݌‬í ‫݋݈ݏ‬ž݁݊‫ ݐݏ݋‬čí‫݊ ݈ܽݏ‬.
Vladimír Mach
Algoritmus
Nechť ࢔ je testované celé liché číslo, ࢑ je celé číslo > 0 určující počet testování.
RabinMillerTest(n, k)
1. Rozložit n na tvar ݊ − 1 = 2௥ ∙ ‫ݏ‬, kde s je liché
2. Vybereme náhodné celé číslo a z rozsahu 1 < a < n
3.
4.
5.
6.
ೕ
Pro každé ݆ = 0, … , ‫ ݎ‬− 1 spočteme ‫ݔ‬௝ = ܽଶ ௦ ݉‫݊ ݀݋‬
Pokud ∄݅, ݅ = 0, … , ‫ ݎ‬− 1 | ‫ݔ‬௜ = −1 & ܽ ௦ ݉‫ ≠ ݊ ݀݋‬1 : vrať n je složené
Kroky 2. – 4. (nazvěme je Testem) opakujeme k-krát
Vrať n je prvočíslo
Pozorování: Umocňování po čtvercích:
‫ہ‬ౢ౥ౝ ೙‫ۂ‬
‫ ݔ‬௞ ‫݋݌ݏ‬č‫ ݔ ݋݆݇ܽ ݁݉݁ݐ‬ଵ , ‫ ݔ‬ଶ , ‫ ݔ‬ସ = ሺ‫ ݔ‬ଶ )ଶ , … , ‫ ݔ‬ଶ మ ,
݇ ‫݋݈ݖ݋ݎ ݅ݏ‬ží݉݁ ݀‫ݒ݋݆݇݋ݒ݀ ݋‬é ‫ ݕݒܽݐݏݑ݋ݏ‬ሺ݇ ‫݉ ݕ݀݁ݐ‬á݉݁ ݆ܽ݇‫ݑ݋ݏ ݋‬č݁‫)ݕ݆݇݋ݒ݀ ݊݅݊ܿ݋݉ ݐ‬
೔
೔
೔
೔
ܽ ݉ůž݁݉݁ ‫݋݌ݏ‬čí‫ ݔ ݐܽݐ‬௞ = ‫ ݔ‬ଶ భ ା⋯ାଶ ೗ = ‫ ݔ‬ଶ భ ∙ … ∙ ‫ ݔ‬ଶ ೗ ,
݈ܿ݁݇݁݉ ‫ݐ݋݌ ݕ݀݁ݐ‬řܾ݁‫ܱ ݆݁݉݁ݑ‬ሺlog ݇) ݊á‫ܾ݊݁݋ݏ‬í.
Časová složitost
Nejdůležitější, a také časově nejnáročnější, operací je mocnění modulo n v 3. kroku algoritmu. Podle
předchozího pozorování spočítáme ‫ ݔ‬௦ (mod n) za ܱሺlog ݊) operací násobení modulo n. Každé
ೕ
násobení, za využití „školního“ algoritmu, nás stojí čas ܱሺlog ଶ ݊). Poté, co spočítáme ‫ ݔ‬௦ další ‫ ݔ‬ଶ ௦
získáme dalším mocněním po čtvercích, které nám opět zabere ܱሺlog ݊) operací modulo n. Když to
dáme dohromady, získáváme časovou složitost ܱሺlog ଷ ݊) pro jeden Test (kroky 2. – 4. v algoritmu).
Protože Test provádíme k-krát, výsledná časová složitost je ࡻሺ࢑ ⋅ ‫ ܏ܗܔ‬૜ ࢔)
Mezi méně náročné operace patří rozklad v prvním kroku, který nás stojí v nejhorším případě
ܱሺlog ݊), než získáme liché ‫ݏ‬.
Pravděpodobnost výsledku
Pokud algoritmus během svého běhu ohlásí, že ݊ je složené, víme zcela jistě, že ݊ prvočíslem není.
Pokud dojde do konce (6. krok algoritmu), je pravděpodobné, že ݊ opravdu prvočíslo bude, ale
nevíme to jistě.
Pravděpodobnost, že se spleteme, závisí na tom, kolikrát opakujeme kroky 2. – 4., parametr k nám
určuje spolehlivost algoritmu. Následující lemma nám pomůže tuto pravděpodobnost vyčíslit.
ࡸࢋ࢓࢓ࢇ: ܲ‫ ݆݁ ݊ ݀ݑ݇݋‬čí‫݋݈ݏ ݋݈ݏ‬ž݁݊é, ‫݋݌ݏ݈݁ܽ ݆݁ݑݐݏ݅ݔ݁ ݇ܽ݌‬ň 3ൗ4 ‫ݒݏ‬ě݀݇ů ܽ ‫ܽݏݖ݋ݎ ݒ‬ℎ‫ ݑ‬1 < ܽ <
݊ ‫݋ݐ‬ℎ‫݋‬, ž݁ ݊ ݆݁ čí‫݋݈ݏ ݋݈ݏ‬ž݁݊é.
Z toho tedy víme, že pokud algoritmus ohlásí, že n je prvočíslo, tak pravděpodobnost toho, že se
ଵ ௞
spleteme, je: ‫ = ݌‬ቀସቁ
Tedy např. pro ݇ = 50
1 ௞
1 ହ଴
1
‫ = ݌‬൬ ൰ = ൬ ൰ = ହ଴ =ሶ 10ିଷ଴
4
4
4
Čím větší ݇ budeme volit, tím lépe budeme minimalizovat chybu.
~2~
Zdroje:
•
•
•
•
Wolfram [http://mathworld.wolfram.com/Rabin-MillerStrongPseudoprimeTest.html]
Martin Mareš - Algoritmy okolo teorie čísel [http://mj.ucw.cz/papers/numth.ps] (9. 1. 2008)
Wikipedia [http://en.wikipedia.org/wiki/Modular_exponentiation]
Fact-Archive Encyclopedia [http://fact-archive.com/encyclopedia/Miller-Rabin_primality_test]
Příloha 1: Implementace Rabin-Millerova testu v jazyce PHP za pomoci knihovny BC Math
(http://php.net/manual/en/book.bc.php), která implementuje práci s dlouhými čísly.
function RabinMillerTest($n, $presnost = 100) {
$s = $n - 1;
$r = 0;
//rozklad cisla $n na $n -1 = 2^$r * $s, kde $s je liché
while($s % 2 == 0) {
$s = $s / 2;
$r++;
}
for($i = 0; $i < $presnost; $i++) {
$a = rand(1, $n - 1);
$x = bcmod(bcpow($a, $s), $n);
if($x == 1)
continue;
$continue = false;
for($j = 0; $j < $r; $j++) {
$x = bcmod(bcpow($a, bcpow(2,$j)*$s), $n);
if($x == $n - 1) {
$continue = true;
break;
}
}
if($continue)
continue;
return false;
}
return true;
}
Funkce RabinMillerTest vrací false pokud je $n číslo složené, jinak true, tj. pokud $n je
pravděpodobně prvočíslem.
~3~
1. Pokud ‫ݔ‬௥ିଵ ≠ 1: vrať n je složené (a je toho svědkem, podle Fermatovy věty)
Předpokládejme, že výběr náhodného čísla z daného intervalu má konstantní složitost ܱሺ1).
Provádíme tyto operace při testování + jejich časová složitost:
1. Rozklad čísla .. ܱሺܰ)
2. Jedno umocnění .. ܱሺܰ ଶ )
Mocnění se provádí O(1 + log n) krát, což dává O(N) mocnění. Celý test opakujeme k-krát.
Tím
Tedy máme časovou složitost ܱሺ1 + ݊ ∙ log ଷ ݊) = ܱሺ݊ ∙ log ଷ ݊) na jedno kolo, které provedeme kkrát. Složitost celkem je ܱሺ݇ ∙ ݊ ∙ log ଷ ݊ + log ݊) = ܱሺ݇ ⋅ ݊ ∙ log ଷ ݊)
získáváme výslednou časovou složitost Oሺ݇ ⋅ ܰ ଷ )
~4~

Podobné dokumenty

Příručka Sinumerik 840D-soustružení

Příručka Sinumerik 840D-soustružení spuštění WinNC přiřazeny speciální funkce pro ovládání programu SINUMERIK a ovládání stroje. Zde vytvořené programy je možno přenést na obráběcí stroj. Při instalaci WinNC je nutno použít variantu ...

Více

NP-úplné a NP-těžké úlohy, Cookeova věta, heuristiky na - OI-Wiki

NP-úplné a NP-těžké úlohy, Cookeova věta, heuristiky na - OI-Wiki - ILP je lineární programování, kde proměnné jsou celá čísla Rozhodovací úloha: Je dán prostý neorientovaný graf G = (V,E) bez smyček a číslo k. Lze graf obarvit pomocí 3 barev? Dokazuje se soustav...

Více

article.download

article.download narodí jako extrémně nezralé, což se týká všech systémů organismu. V takovém případě j pak nutné klást si otázku, v jakých situacích a za jakých podmínek a v jakém modu rozhodování má být poskytnut...

Více