Eratosthenes-algoritmin seula: Python, C++ esimerkki

Eratosthenesin seula on yksinkertaisin alkulukuseula. Se on alkulukualgoritmi, joka etsii kaikki alkuluvut tietyssรค rajassa. Alkulukuseuloja on useita. Esimerkiksi - Eratosthenesin seula, Atkinin seula, Sundaramin seula jne.

Sana "seulaโ€ tarkoittaa aineita suodattavaa astiaa. Siten seula-algoritmi sisรครคn Python ja muut kielet viittaavat algoritmiin alkulukujen suodattamiseksi.

Tรคmรค algoritmi suodattaa alkuluvun pois iteratiivisessa lรคhestymistavassa. Suodatusprosessi alkaa pienimmรคllรค alkuluvulla. Alkuluku on luonnollinen luku, joka on suurempi kuin 1 ja jolla on vain kaksi jakajaa, nimittรคin 1 ja itse luku. Lukuja, jotka eivรคt ole alkulukuja, kutsutaan yhdistelmรคluvuiksi.

Eratosthenes-menetelmรคn seulassa valitaan ensin pieni alkuluku, jonka kaikki kerrannaiset suodatetaan pois. Prosessi suoritetaan silmukassa tietyllรค alueella.

Esimerkiksi:

Otetaan lukualue vรคlillรค 2-10.

Eratosthenes-algoritmin seula

Kun Eratosthenesin seula on kรคytetty, se tuottaa luettelon alkuluvuista 2, 3, 5, 7

Eratosthenes-algoritmin seula

Eratosthenesin algoritmi

Tรคssรค on Eratosthenesin seulan algoritmi:

Vaihe 1) Luo luettelo numeroista 2:sta annettuun alueeseen n. Aloitamme 2:sta, koska se on pienin ja ensimmรคinen alkuluku.

Vaihe 2) Valitse luettelon pienin luku, x (alkuvaiheessa x on 2), selaa luetteloa ja suodata vastaavat yhdistelmรคluvut merkitsemรคllรค kaikki valittujen lukujen kerrannaiset.

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 arvon tulee olla pienempi tai yhtรค suuri kuin n:n neliรถjuuri (x<=Eratosthenesin algoritmi).

Huomautus: Matemaattinen pรครคttely on melko yksinkertainen. Numeroalue n voidaan kertoa seuraavasti:

n=a*b

Jรคlleen n =Eratosthenesin algoritmi*Eratosthenesin algoritmi

= (kerroin pienempi kuin Eratosthenesin algoritmi) * (kerroin suurempi kuin Eratosthenes-algoritmin seula)

Joten ainakin yksi niistรค pรครคtekijรคt tai molempien on oltava <=Eratosthenesin algoritmi. Nรคin ollen matkalla Eratosthenesin algoritmi riittรครค.

Vaihe 5) Nรคiden neljรคn vaiheen jรคlkeen jรคljellรค olevat merkitsemรคttรถmรคt luvut olisivat kaikki alkuluvut kyseisellรค alueella n.

Esimerkiksi:

Otetaan esimerkki ja katsotaan kuinka se toimii.

Tรคssรค esimerkissรค lรถydรคmme luettelon alkuluvuista 2-25. Joten n=25.

Vaihe 1) Ensimmรคisessรค vaiheessa otamme luettelon numeroista 2-25, kun valitsimme n = 25.

Eratosthenesin algoritmi

Vaihe 2) Sitten valitsemme luettelon pienimmรคn luvun, x. Aluksi x=2, koska se on pienin alkuluku. Sitten kuljemme luettelon lรคpi ja merkitsemme 2:n kerrannaiset.

2:n kerrannaiset annetulle n:n arvolle ovat: 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24.

Eratosthenes-algoritmin seula

Huomautus: Sininen vรคri tarkoittaa valittua numeroa, ja vaaleanpunainen vรคri tarkoittaa eliminoituja kerrannaisia

Vaihe 3) Sitten valitaan seuraavaksi pienin merkitsemรคtรถn luku, joka on 3, ja toistetaan viimeinen vaihe merkitsemรคllรค 3:n kerrannaiset.

Eratosthenes-algoritmin seula

Vaihe 4) Toistamme vaihetta 3 samalla tavalla, kunnes x=Eratosthenes-algoritmin seula tai 5.

Eratosthenes-algoritmin seula

Vaihe 5) Loput merkitsemรคttรถmรคt luvut olisivat alkulukuja 2-25.

Eratosthenes-algoritmin seula

Pseudokoodi

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++ koodi esimerkki

#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

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รค Eratosthenesin seulaa vaaditaan ajamaan silmukka koko lukualueen lรคpi. Siten se tarvitsee O(n) muistitilaa numeroiden tallentamiseen. Tilanne muuttuu monimutkaiseksi, kun yritรคmme lรถytรครค alkulukuja valtavalta alueelta. Ei ole mahdollista varata niin suurta muistitilaa isommalle n:lle.

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:

  1. Kรคytรค yksinkertaista seulaa lรถytรครคksesi alkuluvut 2:sta Segmentoitu seula ja tallenna ne joukkoon.
  2. Jaa alue [0โ€ฆn-1] enintรครคn useisiin segmentteihin Segmentoitu seula
  3. Iteroi jokaiselle segmentille segmentti ja merkitse vaiheessa 1 lรถydetty alkulukujen kerrannainen. Tรคmรค vaihe vaatii O(Segmentoitu seula) max.

Tavallinen seula vaatii O(n) apumuistitilaa, kun taas segmentoitu seula vaatii O(nSegmentoitu seula), mikรค on suuri parannus suurelle n. Menetelmรคllรค on myรถs haittapuolensa, koska se ei paranna ajan monimutkaisuutta.

Monimutkaisuusanalyysi

Avaruuden monimutkaisuus:

Eratosthenes-algoritmin yksinkertainen seula vaatii O(n) muistitilaa. Ja segmentoitu seula vaatii
O(Monimutkaisuusanalyysi) aputilaa.

Ajan monimutkaisuus:

Eratosthenes-algoritmin sรครคnnรถllisen seulan aikamonimutkaisuus on O(n*log(log(n))). Tรคmรคn monimutkaisuuden syitรค kรคsitellรครคn alla.

Tietylle luvulle n yhdistelmรคluvun (eli ei-alkulukujen) merkitsemiseen tarvittava aika on vakio. Joten, kuinka monta kertaa silmukka suoritetaan, on yhtรค suuri kuin -

n/2 + n/3 + n/5 + n/7 + โ€ฆโ€ฆโˆž

= n * (1/2 + 1/3 + 1/5 + 1/7 +โ€ฆโ€ฆ.โˆž)

Alkulukujen summan harmoninen eteneminen voidaan vรคhentรครค muodossa log(log(n)).

(1/2 + 1/3 + 1/5 + 1/7 +โ€ฆโ€ฆ.โˆž) = log(log(n))

Joten aika monimutkaisuus tulee olemaan

T(n) = n * (1/2 + 1/3 + 1/5 + 1/7 + โ€ฆโ€ฆโˆž)

= n * log(log(n))

Siten aikakompleksisuus O(n * log(log(n)))

Seuraavaksi opit aiheesta Pascalin kolmio

Yhteenveto

  • Eratosthenesin seula suodattaa pois alkuluvut tietyssรค ylรคrajassa.
  • Alkuluvun suodatus alkaa pienimmรคstรค alkuluvusta "2". Tรคmรค tehdรครคn iteratiivisesti.
  • Iterointi suoritetaan n:n neliรถjuureen asti, missรค n on annettu lukualue.
  • Nรคiden iteraatioiden jรคlkeen jรคljelle jรครคvรคt luvut ovat alkulukuja.

Tiivistรค tรคmรค viesti seuraavasti: