Atkins sikt är en algoritm för att hitta alla primtal upp till ett givet heltal N. Algoritmen skapades av A.O.L. Atkinoch D. Yu. Bernstein[1] [2] . Den asymptotiska hastigheten för algoritmen som deklarerats av författarnamotsvarar hastigheten för de mest tidigare kända siktningsalgoritmerna, men i jämförelse med dem kräver Atkin-sikten mindre minne.
Algoritmens huvudidé är att använda irreducerbara kvadratiska former (representation av tal som axe 2 + med 2 ). De tidigare algoritmerna var i princip olika modifieringar av sikten av Eratosthenes , som använde representationen av tal i form av reducerade former (vanligtvis i form av en produkt xy ).
I en förenklad form kan algoritmen representeras enligt följande:
För att minska minneskraven utförs "siktning" i portioner (segment, block), vars storlek är ungefär .
För att påskynda det hela ignorerar algoritmen alla tal som är multiplar av ett av de första primtal (2, 3, 5, 7, ...). Detta görs genom att använda standarddatastrukturer och databehandlingsalgoritmer som tidigare föreslagits av Paul Pritchard [3 ] . De är kända under det engelska namnet. hjulsiktning . Antalet första primtal väljs beroende på det givna talet N. Teoretiskt föreslås det att de första primtalen tar ungefär upp till . Detta tillåter oss att förbättra den asymptotiska uppskattningen av algoritmens hastighet med faktorn . I detta fall krävs ytterligare minne, som, när N växer, begränsas till . Ökningen av minnesbehov uppskattas till .
Den version som presenteras på en av författarnas webbplats [4] är optimerad för att söka efter alla primtal upp till en miljard ( ), och tal som är multiplar av 2, 3, 5 och 7 exkluderas från beräkningar (2 × 3 × 5 × 7 = 210).
Enligt författarna till [2] har algoritmen asymptotisk komplexitet och kräver minnesbitar . Tidigare var algoritmer kända som var lika asymptotiskt snabba, men som kräver betydligt mer minne [5] [6] . Teoretiskt kombinerar denna algoritm den maximala hastigheten med de lägsta minneskraven. Implementeringen av algoritmen, utförd av en av författarna, visar en ganska hög praktisk hastighet [4] .
Algoritmen använder två typer av optimering, vilket avsevärt ökar dess effektivitet (jämfört med den förenklade versionen).
Nedan är en implementering av en förenklad version i programmeringsspråket C , som illustrerar huvudidén med algoritmen - användningen av kvadratiska former:
int limit = 1000 ; int sqr_lim ; bool är_prime [ 1001 ]; int x2 , y2 ; int i , j ; int n ; // Sieve initialisering sqr_lim = ( int ) sqrt (( lång dubbel ) limit ); för ( i = 0 ; i <= gräns ; ++ i ) is_prime [ i ] = falskt ; is_prime [ 2 ] = sant ; is_prime [ 3 ] = sant ; // Förmodligen är primtal heltal med ett udda antal // representationer i de givna kvadratformerna. // x2 och y2 är i och j kvadrater (optimering). 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 ; om (( n <= gräns ) && ( n % 12 == 1 || n % 12 == 5 )) is_prime [ n ] = ! är_primtal [ n ]; //n = 3 * x2 + y2; n- = x2 ; // Optimering om (( n <= limit ) && ( n % 12 == 7 )) is_prime [ n ] = ! är_primtal [ n ]; //n = 3 * x2 - y2; n- = 2 * y2 ; // Optimering om (( i > j ) && ( n <= limit ) && ( n % 12 == 11 )) is_prime [ n ] = ! är_primtal [ n ]; } } // Sås bort multiplar av kvadraterna av primtal i intervallet [5, sqrt(limit)]. // (huvudstadiet kan inte sålla bort dem) för ( i = 5 ; i <= sqr_lim ; ++ i ) { if ( är_primtal [ i ]) { n = i * i ; för ( j = n ; j <= limit ; j += n ) is_prime [ j ] = falskt ; } } // Skriv ut en lista med primtal till konsolen. printf ( "2, 3, 5" ); for ( i = 6 ; i <= limit ; ++ i ) { // check för delbarhet med 3 och 5 har lagts till. Det finns inget behov av det i den ursprungliga versionen av algoritmen. om (( är_primtal [ i ]) && ( i % 3 != 0 ) && ( i % 5 != 0 )) printf ( ", %d" , i ); }