Eratostheneen seula Python & C++
โก รlykรคs yhteenveto
Eratostheneen seula on klassinen alkulukualgoritmi, joka suodattaa yhdistettyjรค lukuja merkitsemรคllรค iteratiivisesti kunkin alkuluvun monikertoja, jรคttรคen jรคljelle vain alkuluvut valitun ylรคrajan sisรคllรค nopeaa hakua varten.

Mikรค on Eratostheneen seula?
Eratostheneen seula on yksinkertaisin alkulukuseula. Se on alkulukualgoritmi, jota kรคytetรครคn lรถytรคmรครคn kaikki alkuluvut tietyn rajan sisรคllรค. On olemassa useita alkulukuseuloja, mukaan lukien Eratostheneen seula, Atkinin seula ja Sundaramin seula.
Sana "seulaโ viittaa vรคlineeseen, joka suodattaa aineita. Samassa hengessรค seula-algoritmi Python ja muut kielet viittaa menetelmรครคn, joka suodattaa alkuluvut kokonaislukuluettelosta.
Tรคmรค algoritmi suodattaa alkulukuja iteratiivisella lรคhestymistavalla. Suodatusprosessi alkaa pienimmรคstรค alkuluvusta. Alkuluku on luonnollinen luku, joka on suurempi kuin 1 ja jolla on vain kaksi jakajaa, nimittรคin 1 ja itse luku. Numbers jotka eivรคt ole alkulukuja, kutsutaan yhdistettyiksi luvuiksi.
Miksi kรคyttรครค Eratostheneen seulaa?
Eratostheneen seulamenetelmรคssรค valitaan ensin pieni alkuluku ja kaikki sen monikerrat suodatetaan pois. Prosessi toimii silmukassa tietyllรค alueella ja tuottaa tehokkaasti kaikki alkuluvut n:รครคn asti ilman, ettรค jokaiselle ehdokkaalle suoritetaan koejakolaskua.
Tรคmรค tekee seulasta nopeamman kuin alkulukujen tarkistaminen yksitellen. Sitรค kรคytetรครคn laajalti lukuteoriassa, kryptografiassa, hajautuksessa ja kilpailuohjelmoinnissa, joissa on luotava nopeasti useita alkulukuja.
Esimerkiksi:
Otetaan lukuvรคli 2-10.
Eratostheneen seulan levittรคmisen jรคlkeen saadaan lista alkuluvuista 2, 3, 5 ja 7.
Eratosthenesin algoritmi
Tรคssรค on Eratosthenesin seulan algoritmi:
Vaihe 1) Luo lista luvuista 2:sta annettuun vรคliin n. Aloitamme luvusta 2, koska se on pienin ja ensimmรคinen alkuluku.
Vaihe 2) Valitse listalta pienin luku x (aluksi x on 2), kรคy lista lรคpi ja suodata vastaavat yhdistettyjรค luvut merkitsemรคllรค valitun luvun kaikki monikerrat.
Vaihe 3) Valitse sitten luettelosta seuraava alkuluku tai pienin merkitsemรคtรถn luku ja toista vaihe 2.
Vaihe 4) Toista edellinen vaihe, kunnes x:n arvo on pienempi tai yhtรค suuri kuin n:n neliรถjuuri (x<=).
Huomautus: Matemaattinen pรครคttely on melko yksinkertaista. Lukuvรคli n voidaan jakaa tekijรถihin seuraavasti:
n = a * b
Jรคlleen n = *
= (kerroin pienempi kuin ) * (kerroin suurempi kuin
)
Joten ainakin yksi niistรค pรครคtekijรคt tai molempien on oltava <= Siksi ylitys kohti
riittรครค.
Vaihe 5) Nรคiden neljรคn vaiheen jรคlkeen jรคljellรค olevat merkitsemรคttรถmรคt luvut ovat kaikki alkuluvut annetulla vรคlillรค n.
Toiminut esimerkki
Esimerkiksi:
Otetaan esimerkki ja katsotaan, miten se toimii.
Tรคssรค esimerkissรค etsimme alkulukujen luettelon 2:sta 25:een. Joten n = 25.
Vaihe 1) Ensimmรคisessรค vaiheessa otamme listan numeroista 2 - 25, koska valitsimme n = 25.
Vaihe 2) Sitten valitsemme listalta pienimmรคn luvun, x. Aluksi x = 2, koska se on pienin alkuluku. Sitten kรคymme listan lรคpi ja merkitsemme luvun 2 monikerrat.
Annetun n:n arvon 2 monikerrat ovat: 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24.
Huomautus: Sininen vรคri tarkoittaa valittua numeroa ja vaaleanpunainen vรคri eliminoituja monikertoja.
Vaihe 3) Sitten valitaan seuraavaksi pienin merkitsemรคtรถn luku, joka on 3, ja toistetaan viimeinen vaihe merkitsemรคllรค 3:n kerrannaiset.
Vaihe 4) Toistamme vaiheen 3 samalla tavalla, kunnes x = tai 5.
Vaihe 5) Loput merkitsemรคttรถmรคt luvut ovat alkuluvut 2:sta 25:een.
Pseudo-Code
Seuraava pseudokoodi kuvaa Eratostheneen seulan perusrakenteen ennen kuin kรครคnnรคmme sen varsinaiseksi koodiksi.
Begin
Declare a boolean array of size n and initialize it to true
For all numbers i : from 2 to sqrt(n)
IF bool value of i is true THEN
i is prime
For all multiples of i (i<n)
mark multiples of i as composite
Print all unmarked numbers
End
Eratosthenes C/C++ Code esimerkki
Alla on tรคydellinen C++ Eratostheneen seulan toteutus, joka tulostaa kaikki alkuluvut valittuun ylรคrajaan asti.
#include <iostream>
#include <cstring>
using namespace std;
void Sieve_Of_Eratosthenes(int n)
{
// Create and initialize a boolean array
bool primeNumber[n + 1];
memset(primeNumber, true, sizeof(primeNumber));
for (int j = 2; j * j <= n; j++) {
if (primeNumber[j] == true) {
// Update all multiples of i as false
for (int k = j * j; k <= n; k += j)
primeNumber[k] = false;
}
}
for (int i = 2; i <= n; i++)
if (primeNumber[i])
cout << i << " ";
}
int main()
{
int n = 25;
Sieve_Of_Eratosthenes(n);
return 0;
}
lรคhtรถ:
2 3 5 7 11 13 17 19 23
Eratosthenesin seula Python Ohjelmaesimerkki
Seuraavat Python ohjelma toteuttaa saman algoritmin kรคyttรคmรคllรค totuusarvoista listaa ja while-silmukkaa.
def SieveOfEratosthenes(n): # Create a boolean array primeNumber = [True for i in range(n+2)] i = 2 while (i * i <= n): if (primeNumber[i] == True): # Update all multiples of i as false for j in range(i * i, n+1, i): primeNumber[j] = False i += 1 for i in range(2, n): if primeNumber[i]: print(i) n = 25 SieveOfEratosthenes(n)
lรคhtรถ:
2 3 5 7 11 13 17 19 23
Segmentoitu seula
Olemme nรคhneet, ettรค Eratostheneen seula kรคy lรคpi koko lukuvรคlin. Siksi se tarvitsee O(n) muistitilaa lukujen tallentamiseen. Tilanne mutkistuu, kun yritรคmme lรถytรครค alkulukuja valtavalta vรคliltรค, โโkoska ei ole mahdollista varata niin suurta muistilohkoa suuremmalle n luvulle.
Algoritmi voidaan optimoida ottamalla kรคyttรถรถn joitain uusia ominaisuuksia. Ajatuksena on jakaa lukualue pienempiin segmentteihin ja laskea nรคiden segmenttien alkuluvut yksitellen. Tรคmรค on tehokas tapa vรคhentรครค tilan monimutkaisuutta. Tรคtรค menetelmรครค kutsutaan a segmentoitu seula.
Optimointi voidaan tehdรค seuraavalla tavalla:
- Kรคytรค yksinkertaista seulaa lรถytรครคksesi alkuluvut 2:sta
ja tallenna ne joukkoon.
- Jaa alue [0โฆn-1] enintรครคn useisiin segmentteihin
.
- Jokaiselle janalle iteroi jana lรคpi ja merkitse vaiheessa 1 lรถydettyjen alkulukujen monikerrat. Tรคmรค vaihe vaatii O(
) enintรครคn.
Tavallinen seula vaatii O(n) apumuistitilaa, kun taas segmentoitu seula vaatii O(n), mikรค on huomattava parannus suurella n:llรค. Menetelmรคllรค on myรถs haittapuolensa, koska se ei paranna aikakompleksisuutta.
Monimutkaisuusanalyysi
Sekรค tila- ettรค aikakompleksisuuden ymmรคrtรคminen auttaa sinua valitsemaan tavallisen seulan ja segmentoidun seulan vรคlillรค tietyn ongelman koon mukaan.
Avaruuden monimutkaisuus:
Yksinkertainen Eratostheneen seula-algoritmi vaatii O(n) muistitilaa. Segmentoitu seula vaatii O() aputilaa.
Ajan monimutkaisuus:
Eratostheneen seula-algoritmin aikavaativuus on O(n*log(log(n))). Tรคmรคn monimutkaisuuden taustalla olevia perusteluja kรคsitellรครคn alla.
Annetulla luvulla n yhdistettyjen lukujen (eli alkuluvuista poikkeavien lukujen) merkitsemiseen kuluva aika on vakio. Joten silmukan suorituskertojen mรครคrรค on yhtรค suuri kuin:
n/2 + n/3 + n/5 + n/7 + โฆโฆโ
= n * (1/2 + 1/3 + 1/5 + 1/7 +โฆโฆ.โ)
Alkulukujen summan harmoninen johdanto voidaan pรครคtellรค muodossa log(log(n)):
(1/2 + 1/3 + 1/5 + 1/7 +โฆโฆ.โ) = log(log(n))
Joten aikakompleksisuus on:
T(n) = n * (1/2 + 1/3 + 1/5 + 1/7 + โฆโฆโ)
= n * log(log(n))
Nรคin ollen aikakompleksisuus on O(n * log(log(n))).
Seuraavaksi opit mm. Pascalin kolmio.







