Sita lui Atkin este un algoritm pentru găsirea tuturor numerelor prime până la un număr întreg dat N. Algoritmul a fost creat de A. O. L. Atkinși D. Yu. Bernstein[1] [2] . Viteza asimptotică a algoritmului declarată de autoricorespunde vitezei celor mai bine cunoscuți algoritmi de cernere, dar în comparație cu aceștia, sita Atkin necesită mai puțină memorie.
Ideea principală a algoritmului este de a folosi forme pătratice ireductibile (reprezentarea numerelor ca ax 2 + cu 2 ). Algoritmii anteriori erau practic diverse modificări ale site-ului lui Eratosthenes , care foloseau reprezentarea numerelor sub formă de forme reduse (de obicei sub forma unui produs xy ).
Într-o formă simplificată, algoritmul poate fi reprezentat după cum urmează:
Pentru a reduce cerințele de memorie, „cernerea” se realizează în porțiuni (segmente, blocuri), a căror dimensiune este de aproximativ .
Pentru a accelera lucrurile, algoritmul ignoră toate numerele care sunt multiple ale unuia dintre primele câteva numere prime (2, 3, 5, 7, ...). Acest lucru se realizează prin utilizarea structurilor de date standard și a algoritmilor de procesare a datelor propuși anterior de Paul Pritchard [3 ] . Ele sunt cunoscute sub numele englezesc. cernerea rotii . Numărul primelor prime este ales în funcție de numărul dat N. Teoretic, se propune ca primele numere prime aproximativ până la . Acest lucru ne permite să îmbunătățim estimarea asimptotică a vitezei algoritmului cu un factor . În acest caz, este necesară o memorie suplimentară, care, pe măsură ce N crește, este mărginită ca . Creșterea cerințelor de memorie este estimată ca .
Versiunea prezentată pe site-ul unuia dintre autori [4] este optimizată pentru căutarea tuturor numerelor prime de până la un miliard ( ), iar numerele care sunt multipli de 2, 3, 5 și 7 sunt excluse din calcule (2 × 3 × 5 × 7 = 210).
Potrivit autorilor din [2] , algoritmul are complexitate asimptotică și necesită biți de memorie. Anterior, se știau algoritmi care erau la fel de rapidi asimptotic, dar necesită mult mai multă memorie [5] [6] . Teoretic, acest algoritm combină viteza maximă cu cele mai mici cerințe de memorie. Implementarea algoritmului, realizată de unul dintre autori, arată o viteză practică destul de mare [4] .
Algoritmul folosește două tipuri de optimizare, care îi sporesc semnificativ eficiența (comparativ cu versiunea simplificată).
Mai jos este o implementare a unei versiuni simplificate în limbajul de programare C , ilustrând ideea principală a algoritmului - utilizarea formelor pătratice:
int limit = 1000 ; int sqr_lim ; bool este_prim [ 1001 ]; int x2 , y2 ; int i , j ; int n ; // Sieve initialization sqr_lim = ( int ) sqrt (( long double ) limit ); pentru ( i = 0 ; i <= limită ; ++ i ) is_prim [ i ] = fals ; este_prim [ 2 ] = adevărat ; este_prim [ 3 ] = adevărat ; // Probabil că primele sunt numere întregi cu un număr impar // de reprezentări în formele pătrate date. // x2 și y2 sunt pătrate i și j (optimizare). x2 = 0 ; pentru ( i = 1 ; i <= sqr_lim ; ++ i ) { x2 += 2 * i - 1 ; y2 = 0 ; pentru ( j = 1 ; j <= sqr_lim ; ++ j ) { y2 += 2 * j - 1 ; n = 4 * x2 + y2 ; dacă (( n <= limită ) && ( n % 12 == 1 || n % 12 == 5 )) este_prim [ n ] = ! este_prim [ n ]; // n = 3 * x2 + y2; n -= x2 ; // Optimizare dacă (( n <= limită ) && ( n % 12 == 7 )) este_prim [ n ] = ! este_prim [ n ]; // n = 3 * x2 - y2; n -= 2 * y2 ; // Optimizare dacă (( i > j ) && ( n <= limită ) && ( n % 12 == 11 )) este_prim [ n ] = ! este_prim [ n ]; } } // Îndepărtează multiplii pătratelor primelor în intervalul [5, sqrt(limit)]. // (scena principală nu le poate elimina) pentru ( i = 5 ; i <= sqr_lim ; ++ i ) { dacă ( este_prim [ i ]) { n = i * i ; pentru ( j = n ; j <= limită ; j += n ) is_prim [ j ] = fals ; } } // Imprimă o listă de numere prime pe consolă. printf ( "2, 3, 5" ); pentru ( i = 6 ; i <= limită ; ++ i ) { // a fost adăugată verificarea divizibilității cu 3 și 5. Nu este nevoie de aceasta în versiunea originală a algoritmului. dacă (( este_prim [ i ]) && ( i % 3 != 0 ) && ( i % 5 != 0 )) printf ( ", %d" , i ); }