|
Serwis Edukacyjny w I-LO w Tarnowie
Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2026 mgr Jerzy Wałaszek
|
ProblemW przedziale liczb naturalnych |
Sito Atkina-Bernsteina (ang. Atkin-Bernstein Sieve) należy do nowoczesnych algorytmów wyszukujących liczby pierwsze w przedziale od 2 do zadanej liczby naturalnej n. Jest to zoptymalizowany algorytm w stosunku do starożytnego sita Eratostenesa, który najpierw wykonuje wstępne przetwarzanie zbioru liczb, a następnie wyrzuca z niego wszystkie wielokrotności kwadratów początkowych liczb pierwszych zamiast samych liczb pierwszych. Twórcami algorytmu są dwaj profesorowie z University of Illinois w Chicago: Arthur Oliver Lonsdale Atkin – emerytowany profesor matematyki oraz Daniel Julius Bernstein – profesor matematyki, kryptolog i programista.
Przedstawiony poniżej algorytm i jego realizacja nie są optymalne. Umieściłem je tutaj ze względów dydaktycznych. Prawdziwą implementację sita Atkina można znaleźć na stronie domowej prof. Bernsteina, czyli u źródeł i tam odsyłam wszystkich zainteresowanych tym tematem.
W przeciwieństwie do sita Eratostenesa, sito Atkina-Bernsteina rozpoczyna pracę ze zbiorem S, w którym wszystkie liczby są zaznaczone jako złożone (czyli nie pierwsze). Ma to sens, ponieważ algorytm ignoruje kompletnie liczby podzielne przez 2, 3 lub 5. Zaoszczędzamy czas na wyrzucaniu ich ze zbioru.
Algorytm opiera swoje działanie na następujących faktach matematycznych:
K01: Dla i = 5, 6, …, n: ; inicjujemy zbiór liczbowy – wszystkie wykonuj S[i] ← false ; liczby zaznaczamy jako liczby złożone K02: g ← [sqr(n)] ; granica wyznaczania początkowych liczb pierwszych K03: Dla każdego (x, y) z <1; g>: ; szukamy rozwiązań równań kwadratowych wykonuj kroki K04…K12 K04: xx ← x×x ; xx = x2 K05: yy ← y×y ; yy = y2 K06: z ← (xx shl 2)+yy ; z = 4x2+y2 K07: Jeśli (z ≤ n) ∧ (z mod 12 = 1 ∨ z mod 12 = 5), ; jeśli spełnione to S[z] ← ¬S[z] ; są warunki, zmieniamy na przeciwny stan liczby w S K08: z ← z-xx ; z = 3x2+y2 K09: Jeśli (z ≤ n) ∧ (z mod 12 = 7), to S[z] ← ¬S[z] K10: Jeśli x ≤ y, ; ostatnie równanie sprawdzamy tylko dla x > y to następny obieg pętli K03 K11: z ← z-(yy shl 1) ; z = 3x2-y2 K12: Jeśli (z ≤ n) ∧ (z mod 12 = 11), to S[z] ← ¬S[z] K13: Dla i = 5, 6, …, g: ; eliminujemy sitem liczby złożone wykonuj kroki K14…K18 K14: Jeśli S[i] = false, to następny obieg pętli K13 K15: xx = i×i ; z S eliminujemy wielokrotności z ← xx ; kwadratów liczb pierwszych K16: Dopóki z ≤ n, wykonuj kroki K17…K18 K17: S[z] ← false K18: z ← z+xx K19: Pisz 2 3 ; dwie pierwsze liczby wyprowadzamy bezwarunkowo K20: Dla i = 5, 6, …, n: ; przeglądamy zbiór wypisując znalezione wykonuj krok K21 ; liczby pierwsze K21: Jeśli S[i], to pisz i K22: Zakończ
|
Uwaga: Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
| Program w pierwszym wierszu czyta liczbę n i w następnych wierszach wypisuje kolejne liczby pierwsze zawarte w przedziale od 2 do n. |
Pascal// Sito Atkina-Bernsteina
// Data: 21.03.2008
// (C)2020 mgr Jerzy Wałaszek
//---------------------------
program prg;
type
Tbarray = array of boolean;
var n, g, x, y, xx, yy, z, i : longword;
S : Tbarray;
begin
readln(n);
setlength(S, n+1);
for i := 5 to n do S[i] := false;
g := round(sqrt(n));
for x := 1 to g do
begin
xx := x*x;
for y := 1 to g do
begin
yy := y*y;
z := (xx shl 2)+yy;
if(z <= n) and ((z mod 12 = 1) or (z mod 12 = 5)) then
S[z] := not S[z];
dec(z, xx);
if(z <= n) and (z mod 12 = 7) then
S[z] := not S[z];
if(x > y) then
begin
dec(z, yy shl 1);
if(z <= n) and (z mod 12 = 11) then
S[z] := not S[z];
end;
end;
end;
for i := 5 to g do
if S[i] then
begin
xx := i*i;
z := xx;
while z <= n do
begin
S[z] := false;
inc(z, xx);
end;
end;
write(2, ' ', 3, ' ');
for i := 5 to n do
if S[i] then
write(i, ' ');
writeln;
end. |
// Sito Atkina-Bernsteina
// Data: 21.03.2008
// (C)2020 mgr Jerzy Wałaszek
//----------------------------
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
unsigned int n, g, x, y, xx, yy, z, i;
bool * S;
cin >> n;
S = new bool[n+1];
for(i = 5; i <= n; i++)
S[i] = false;
g = (unsigned int)(sqrt(n));
for(x = 1; x <= g; x++)
{
xx = x*x;
for(y = 1; y <= g; y++)
{
yy = y*y;
z = (xx << 2)+yy;
if((z <= n) && ((z % 12 == 1) || (z % 12 == 5)))
S[z] = !S[z];
z -= xx;
if((z <= n) && (z % 12 == 7))
S[z] = !S[z];
if(x > y)
{
z -= yy << 1;
if((z <= n) && (z % 12 == 11))
S[z] = !S[z];
}
}
}
for(i = 5; i <= g; i++)
if(S[i])
{
xx = i*i;
z = xx;
while(z <= n)
{
S[z] = false;
z += xx;
}
}
cout << 2 << " " << 3 << " ";
for(i = 5; i <= n; i++)
if(S[i]) cout << i << " ";
cout << endl;
delete [] S;
return 0;
} |
Basic' Sito Atkina-Bernsteina
' Data: 21.03.2008
' (C)2020 mgr Jerzy Wałaszek
'---------------------------
Dim As Uinteger n, g, x, y, xx, yy, z, i
Input n
Dim As Byte S(n+1)
For i = 5 To n
S(i) = 0
Next
g = Cuint(Sqr(n))
For x = 1 To g
xx = x*x
For y = 1 To g
yy = y*y
z = (xx Shl 2)+yy
if(z <= n) And ((z Mod 12 = 1) Or _
(z Mod 12 = 5)) Then _
S(z) = 1-S(z)
z -= xx
if(z <= n) And (z Mod 12 = 7) Then _
S(z) = 1-S(z)
if(x > y) Then
z -= yy Shl 1
if(z <= n) And (z Mod 12 = 11) Then _
S(z) = 1-S(z)
End If
Next
Next
For i = 5 To g
If S(i) = 1 Then
xx = i*i
z = xx
While z <= n
S(z) = 0
z += xx
Wend
End If
Next
Print 2;" ";3;" ";
For i = 5 To n
If S(i) Then _
Print i;" ";
Next
Print
End |
Python (dodatek)# Sito Atkina-Bernsteina
# Data: 11.02.2024
# (C)2024 mgr Jerzy Wałaszek
# ---------------------------
import math
n = int(input())
s = [False]*(n+1)
g = int(math.sqrt(n))
for x in range(1, g+1):
xx = x*x
for y in range(1, g+1):
yy = y*y
z = (xx << 2)+yy
if (z <= n) and \
((z%12 == 1) or (z%12 == 5)):
s[z] = not s[z]
z -= xx
if (z <= n) and (z%12 == 7):
s[z] = not s[z]
if x > y:
z -= yy << 1
if (z <= n) and (z%12 == 11):
s[z] = not s[z]
for i in range(5, g+1):
if s[i]:
xx = i*i
z = xx
while z <= n:
s[z] = False
z += xx
print(2, 3, end=" ")
for i in range(5, n+1):
if s[i]:
print(i, end=" ")
print()
|
| Wynik: |
100 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 |
JavaScript<html>
<head>
<title>
Sito Atkina-Bernsteina
</title>
</head>
<body>
<div style="overflow-x: auto;"
align="center">
<table
border="0"
cellpadding="4"
style="border-collapse:
collapse">
<tr>
<td nowrap>
<form
name="frm"
style="text-align: center;
background-color:
#E7E7DA">
<b>
Sito Atkina-Bernsteina
</b><br/>
(C)2026
mgr Jerzy Wałaszek
<hr>
n = <input
type="text"
name="inp_n"
size="16"
value="100"
style="text-align:
right">
<hr>
<input
type="button"
value="Wykonaj"
name="B1"
onclick="main()">
<hr>
<b>Wynik:</b>
<div id="out">.</div>
</form>
</td>
</tr>
</table>
</div>
<script type=text/javascript
language=javascript>
// Sito Atkina-Bernsteina
// Data : 21.03.2008
// (C)2008 mgr Jerzy Wałaszek
//----------------------------
function main()
{
var c,n,g,x,y,xx,yy,z,i,t,S;
n = parseInt(document.frm
.inp_n.value);
c = 0;
if(!isNaN(n))
{
S = new Array(n + 1);
for(i = 5; i <= n; i++)
S[i] = false;
g = Math.floor(Math.sqrt(n));
for(x = 1; x <= g; x++)
{
xx = x * x;
for(y = 1; y <= g; y++)
{
yy = y * y;
z = (xx << 2)+yy;
if((z <= n) && ((z % 12 == 1) ||
(z % 12 == 5)))
S[z] = !S[z];
z -= xx;
if((z <= n) &&
(z % 12 == 7))
S[z] = !S[z];
if(x>y)
{
z -= yy << 1;
if((z <= n) &&
(z % 12 == 11))
S[z] = !S[z];
}
}
}
for(i = 5; i <= g; i++)
if(S[i])
{
xx = i * i;
z = xx;
while(z <= n)
{
S[z] = false;
z += xx;
}
}
t = "2 3 ";
for(i = 5; i <= n; i++)
if(S[i])
{
t += i+" ";
c++;
if(c == 10)
{
c = 0;
t += "<br/>";
}
}
}
else t = "Złe dane wejściowe!";
document.getElementById ("out")
.innerHTML = t;
}
</script>
</body>
</html>
|
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.