Atkinovo síto je algoritmus pro nalezení všech prvočísel až do daného celého čísla N. Algoritmus vytvořil A. O. L. Atkina D. Yu Bernstein[1] [2] . Asymptotická rychlost algoritmu deklarovaná autoryodpovídá rychlosti nejznámějších dříve známých sítovacích algoritmů, ale ve srovnání s nimi vyžaduje Atkinovo síto méně paměti.
Hlavní myšlenkou algoritmu je použití neredukovatelných kvadratických forem (reprezentace čísel jako ax 2 + x 2 ). Předchozí algoritmy byly v podstatě různé modifikace Eratosthenova síta , které využívaly reprezentaci čísel ve formě redukovaných forem (obvykle ve formě součinu xy ).
Ve zjednodušené formě může být algoritmus reprezentován následovně:
Pro snížení nároků na paměť se „prosévání“ provádí po částech (segmentech, blocích), jejichž velikost je přibližně .
Aby se to urychlilo, algoritmus ignoruje všechna čísla, která jsou násobky jednoho z prvních několika prvočísel (2, 3, 5, 7, ...). To se provádí pomocí standardních datových struktur a algoritmů pro zpracování dat navržených dříve Paulem Pritchardem [3 ] . Jsou známé pod anglickým názvem. kolo prosévání . Počet prvočísel se volí v závislosti na daném počtu N. Teoreticky se navrhuje brát první prvočísla přibližně do . To nám umožňuje zlepšit asymptotický odhad rychlosti algoritmu o faktor . V tomto případě je vyžadována další paměť, která je s rostoucím N omezena jako . Nárůst požadavků na paměť se odhaduje jako .
Verze prezentovaná na webu jednoho z autorů [4] je optimalizována pro vyhledávání všech prvočísel do miliardy ( ), z výpočtů jsou vyloučena čísla, která jsou násobky 2, 3, 5 a 7 (2 × 3 × 5 × 7 = 210).
Podle autorů [2] má algoritmus asymptotickou složitost a vyžaduje bity paměti. Dříve byly známy algoritmy, které byly stejně asymptoticky rychlé, ale vyžadovaly podstatně více paměti [5] [6] . Teoreticky tento algoritmus kombinuje maximální rychlost s nejnižšími požadavky na paměť. Implementace algoritmu, provedená jedním z autorů, vykazuje poměrně vysokou praktickou rychlost [4] .
Algoritmus využívá dva typy optimalizace, které výrazně zvyšují jeho efektivitu (oproti zjednodušené verzi).
Níže je implementace zjednodušené verze v programovacím jazyce C , která ilustruje hlavní myšlenku algoritmu - použití kvadratických forem:
int limit = 1000 ; int sqr_lim ; bool je_prvočíslo [ 1001 ]; int x2 , y2 ; int i , j ; int n ; // Inicializace síta sqr_lim = ( int ) sqrt (( long double ) limit ); pro ( i = 0 ; i <= limit ; +++ i ) is_prime [ i ] = false ; is_prime [ 2 ] = true ; is_prime [ 3 ] = true ; // Pravděpodobně prvočísla jsou celá čísla s lichým počtem // zobrazení v daných čtvercových tvarech. // x2 a y2 jsou i a j čtverce (optimalizace). x2 = 0 ; for ( i = 1 ; i <= sqr_lim ; ++ i ) { x2 += 2 * i - 1 ; y2 = 0 ; for ( j = 1 ; j <= sqr_lim ; ++ j ) { y2 += 2 * j - 1 ; n = 4 * x2 + y2 ; if (( n <= limit ) && ( n % 12 == 1 || n % 12 == 5 )) is_prime [ n ] = ! je_prvočíslo [ n ]; // n = 3 * x2 + y2; n- = x2 ; // Optimalizace if (( n <= limit ) && ( n % 12 == 7 )) is_prime [ n ] = ! je_prvočíslo [ n ]; // n = 3 * x2 - y2; n- = 2 * y2 ; // Optimalizace if (( i > j ) && ( n <= limit ) && ( n % 12 == 11 )) is_prime [ n ] = ! je_prvočíslo [ n ]; } } // Vyřazení násobků druhých mocnin prvočísel v intervalu [5, sqrt(limit)]. // (hlavní scéna je nemůže vyřadit) for ( i = 5 ; i <= sqr_lim ; ++ i ) { if ( is_prime [ i ]) { n = i * i ; pro ( j = n ; j <= limit ; j += n ) is_prime [ j ] = false ; } } // Tisk seznamu prvočísel do konzole. printf ( "2, 3, 5" ); for ( i = 6 ; i <= limit ; ++ i ) { // byla přidána kontrola dělitelnosti 3 a 5. V původní verzi algoritmu to není potřeba. if (( is_prime [ i ]) && ( i % 3 != 0 ) && ( i % 5 != 0 )) printf ( ", %d" , i ); }