Stan Paul Horaţiu Grupa 226
Generarea numerelor prime industriale
Obiectiv Dorim să generăm numere prime mari, cu un număr de cifre p dat. Spre exemplu pentru p=2 un număr peim format din 2 cifre este 11. Pentru un p mic, până la 5 putem genera numere prime relativ uşor. Dacă p=3 atunci pornim de la 100 şi mergem până la 999 şi pentru fiecare număr din această multime excluzând numerele pare, testăm dacă este prim sau nu. Dacă este prim îl tipărim şi oprim execuţia programului. Pentru parcurgerea numerelor de la 10p la 10p+1-1 sărind peste cele pare avem nevoie de
operaţii, deci complexitatea algoritmului de parcurgere este O(10p), deci exponenţială după numărul cifrelor.
Pentru testarea primalităţii unui
număr n sunt necesari
Deci ordinul total de complexitate al algoritmului este O(10p), practic pentru un număr cu 100 de cifre problema este nerezolvabilă cu acest algoritm. Voi prezenta o metodă de generare de numere prime mari care se bazează pe noţiuni probabilistice. Vom spune că un număr n este prim cu o probabilitate p (mai mare sau mai mică).
Densitatea numerelor prime Numerele prime nu sunt “prea rare”. Spre exemplu să considerăm mulţimea de numere M={0,1,2,3,4,5,6,7,8,9}. Numerele prime din această mulţime sunt P={1,2,3,5,7} deci |P|=5 iar |M|=10, rezultă că probabilitatea ca alegând la întâmplare un număr din M acesta să fie prim este 1/2; deci dacă extragem la întâmplare două numere din M avem şanse mari ca măcar unul să fie prim. Vom putea lucra în continuare cu aceste două numere nu cu toate cele 10.
Fie funcţia
Graficul funcţiei
Teorema numărului numerelor prime Această teoremă dă o aproximare a funcţiei de distribuţie a numerelor prime. Teorema 1 (Teorema numărului numerelor prime)
Această aproximare este
destul de bună, pentru n=109
Putem folosi teorema numărului numerelor prime pentru a estima probabilitatea ca un întreg n ales la întâmplare să fie prim.
În mulţimea M={1,…,n}
avem
Deci va trebui să
examinăm
Testul de pseudoprimalitate Spunem ca n este pseudoprim cu baya a dacă n este compus si
Teorema 2 (mica teoremă a lui Fermat) Dacă p este prim atunci
Corolar 2.1 Dacă reuşim să găsim un a pentru care (1) să nu fie adevărată atunci n este cu siguranţă compus. Vom verifica dacă un n satisface relaţia (1) pentru a=2. Dacă nu, atunci el este compus, altfel presupunem că n este prim. (de fapt n este pseudo prim relativ la baza 2). Pentru a face testul trebuie să calculăm 2n-1 (mod n). Am putea face un ciclu for de la 1 la n-1 şi să tot înmulţim rezultatul cu 2 şi apoi să reţinem restul împărţirii la n. Presupunând că fiecare operaţie din ciclul for se execută într-un timp constant ordinul de complexitate al algoritmului este O(n)=O(10p) (am presuus că n are p cifre) deci exponenţial după numărul cifrelor.
Ridicarea la putere prin ridicări repetate la pătrat Ne propunem să calculăm ab(mod n). Exemplu:
pentru a=3 b=5 n=7 avem
observăm că putem calcula
La fiecare pas vom
împărţii puterea b la 2, dacă restul împărţirii este 1
atunci rezultatul va fi egal cu a înmulţit cu rezultatul
ridicării lui a la puterea b-1, iar dacă restul este 0
atunci rezultatul va fi egal cu produsul
Deci formula recursivă poate fi scrisă astfel:
unde
Dezavantajul acestei formule este că unele calcule se fac de 2 ori. Această formulă recursivă de calcul este echivalentă cu următorul algoritm:
Functia exp_mod(a,b,n) {calculeaza a la puterea b modulo n} dß1; fie <bk,bk-1,...,b0> reprezentarea binara a lui b; pentru ißk,0,-1 executa dß(d*d)mod n; daca bi=1 atunci dß(d*a)mod n; sfd; sfpt; expßd; sfexp;
Acest algoritm are ordinul de complexitate O(ln(b)). Având în vedere că pe postul lui b în testul de pseudoprimalitate se află n-1 avem ordinul de complexitate O(ln(n-1)) deci O(ln(10p))=O(p), adică liniar în raport cu cifrele exponentului. Testul de pseudoprimalitate îl putem descrie într-un algoritm astfel:
Functia pseudoprim(n) {verifica daca n este pseudoprim relativ la baza 2} daca exp(2,n-1,n)=1 atunci pseudoprimßcompus; {rezultat definitiv} altfel pseudoprimßprim; {speram} sfd; sfpseudoprim
Dacă funcţia întoarce “prim” s-ar putea să greşească. Cât de des poate să apară această greşeală? Există numai 22 de valori ale lui n mai mici decât 10000 pt care ea este eronată. Se poate arăta că dacă numărul cifrelor lui n tinde la infinit atunci eroarea acestei funcţii tinde la 0. Am putea schimba baza, în loc de 2 să punem 3 (de exemplu), astfel am elimina câteva numere din cele 22. Din nefericire însă există numere pentru care oricum am alege baza ele scapă de testul de pseudoprimalitate chiar dacă nu sunt prime. Aceste numere se numesc numere Carmichael. Primele 3 numere Carmichael sunt: 561, 1105, 1729.
Testul aleator de primalitate al lui Miller-Rabin Acest test se bazează pe următorul rezultat: Teorema 3 Dacă p este un număr prim impar şi e>0 atunci ecuaţia:
are numai soluţiile x=1 şi x=-1. Un număr x este o rădăcină netrivială a ecuaţiei (2) dacă verifică relaţia (2) şi x nu este egal cu 1 sau -1. Testul de numar prim al lui Miller-Rabin îmbunătăţeşte testul de pseudoprimalitate prin două modificări: 1) Încearcă să aleagă diferite valori ale bazei a spre deosebire de testul de pseudoprimalitate care are o sigură valoare pentru a. 2) În timp ce calculează fiecare exponenţiere modulară, stabileşte dacă nu cumva a fost găsită o rădăcină netrivială a ecuaţiei (2). Dacă aşa ceva se întâmplă atunci returnează compus. Vom utiliza o funcţie auxiliară Test, astfel încât Test(a,n) este adevărat dacă şi numai dacă a şi n satisfac relaţia (2). Această funcţie este similară testului de pseudoprimalitate dar este mult mai eficientă. Voi prezenta mai întâi funcţia Test şi apoi voi explica algoritmul.
Functia Test(a,n) {returneaza adevarat daca a ridicat la puterea n-1 modulo n este egal cu 1 si fals altfel} fie <bk,bk-1,...,b0> reprezentarea binara a lui n-1; dß1; pentru ißk,0,-1 executa xßd; dß(d*d)mod n; daca d=1 si x<>1 si x<>n-1 atunci Testßadevarat;{caz 1} sfd daca bi=1 atunci dß(d*a)mod n; sfd; sfpt; daca d<>1 atunci Testßadevarat;{caz 2} Sfd; Testßfals; sfTest;
Funcţia Test se bazează
pe algoritmul de exponenţiere modulară. Dacă funcţia
Test returnează adevărat în caz 2 atunci am găsit că
Dacă Test returnează adevărat atunci n nu este prim altfel s-ar putea ca n să fie prim cu o probabilitate destul de mare. Voi prezenta acum algoritmul lui Miller-Rabin care utilizează funcţia Test pentru verificarea faptului că n nu este prim.
Functia Miller_Rabin(n,s) {testeaza daca n este prim prin alegerea la intamplare a s numere intre 1 si n-1 care sa fie baza in apelul functiei Test} pentru jß1,s executa aßRandom(1,n-1);{alege un numar intre 1 si n-1} daca Test(a,n)=adevarat atunci Miller_Rabinßcompus;{sigur} Sfd; Sfpt; Miller_Rabinßprim;{aproape sigur} SfMiller_Rabin;
Dacă din s încercări nu se găseşte nici o bază cu care n să fie pseudoprim şi nu se găseşte nici o soluţie a ecuaţiei (2) atunci algoritmul presupune că că n este prim. Cu cât s este mai mare cu atât avem o siguranţă mai mare a faptului că n este prim. Dacă n este un număr cu p cifre atunci complexitatea algoritmului este O(s*p).
Cât de sigur este algoritmul lui Miller-Rabin ? Dacă algoritmul returnează compus atunci suntem siguri ca n nu este prim, iar dacă returnează prim atunci există o mică şansă de eroare. Spre deosebire de testul de pseudoprimalitate eroarea nu depinde de n, nu există intrări defavorabile pentru acest subalgoritm. Rata de eroare depinde de dimensiunea lui s şi de “norocul” avut la alegerea bazei a. Teorema 4 Pentru orice întreg impar n>2 şi orice intreg s >0 probabilitatea ca Miller_Rabin(n,s) să greşească este cel mult 2-s. Astfel, s=50 ar trebui să fie suficient pentru aproape orice aplicaţie imaginabilă.
Algoritmul de generare industrială de numere prime Pentru a genera un număr prim de p cifre am spus că avem nevoie de ln(n) numere.
Functia genereaza(p,s) {returneaza un numar prim de p cifre cu o probabilitate de 2-s returneaza -1 daca nu reuseste sa genereze un astfel de numar} nßRandom(p);{returneaza un numar aleator de p cifre} pentru iß1,ln(n) executa daca Miller_Rabin(n,s)=prim atunci genereazaßn; sfd; nßn+1; daca n are p+1 cifre atunci nß10p; sfd; sfpt; genereazaß-1; Sfgenereaza;
Complexitatea acestui algoritm este O(s*p2), deci polinomială în raport cu numărul cifrelor numărului care se doreste a fi generat spre deosebire de testul de forţă brută care are o complexitate exponenţială în raport cu numprul cifrelor numărului care se doreşte a fi generat.
Program de generare demonstrativ Programul genereaza un număr prim aleator de p cifre cu probabilitatea 1-.2-s. Dacă nu va reuşii generarea unui astfel de număr atunci va returna un mesaj de eroare. descarcă întreg referatul în format doc
Bibliografie 1) Introducere în algoritmi de Thomas H. Cormen, Charles E. Leiserson, Ronald R. Rivest 2) Curs de Algebră Computaţională Universitatea Babeş Bolyai Cluj-Napoca Facultatea de Matematică si Informatică secţia Informatică anul 2 semestrul 2 de Lect. Dr. SACAREA Cristian 3) mathworld.wolfram.com 4) www.free-definition.com
|