Eratosthenes' si i Python & C++

⚡ Smart opsummering

Eratosthenes' si er en klassisk primtalsalgoritme, der filtrerer sammensatte tal ved iterativt at markere multipla af hvert primtal, så kun primtal inden for en valgt øvre grænse efterlades til hurtig opslag.

  • 🔢 Kerneidé: Marker multipla af hvert primtal startende fra 2 for at isolere primtal op til n.
  • 🧮 Løkkebundet: Iterer kun op til kvadratroden af ​​n, fordi større faktorer allerede er elimineret.
  • Tidskompleksitet: Algoritmen kører i O(n log log n), hvilket er næsten lineært for praktiske intervaller.
  • Segmenteret si: Opdeling af området i blokke reducerer hjælpehukommelsen fra O(n) til O(√n).
  • 🧪 Brug sager: Kryptografi, hashing, konkurrencepræget programmering og talteori er afhængige af hurtig generering af primtal.

Eratosthenes' si i Python

Hvad er Eratosthenes' si?

Eratosthenes-sigten er den enkleste primtalssigte. Det er en primtalsalgoritme, der bruges til at opdage ethvert primtal inden for en given grænse. Der findes adskillige primtalssigter, herunder Eratosthenes-sigten, Atkins-sigten og Sundarams-sigten.

Ordet "sigte" henviser til et redskab, der filtrerer stoffer. I samme ånd anvendes sialgoritmen i Python og andre sprog refererer til en metode, der filtrerer primtal fra en liste af heltal.

Denne algoritme filtrerer primtal ved hjælp af en iterativ tilgang. Filtreringsprocessen starter med det mindste primtal. Et primtal er et naturligt tal større end 1, der kun har to divisorer, nemlig 1 og selve tallet. Numbers der ikke er primtal, kaldes sammensatte tal.

Hvorfor bruge Eratosthenes-sigten?

I Eratosthenes-si-metoden vælges et lille primtal først, og alle multipla af det filtreres fra. Processen kører i en løkke på tværs af et givet interval, hvor hvert primtal op til n produceres effektivt uden at udføre prøvedivision på hver kandidat.

Dette gør sigten hurtigere end at kontrollere primtal ét tal ad gangen. Den bruges i vid udstrækning i talteori, kryptografi, hashing og konkurrencepræget programmering, hvor mange primtal skal genereres hurtigt.

For eksempel:

Lad os tage talområdet fra 2 til 10.

Sigte af Eratosthenes-algoritmen

Efter at have anvendt Eratosthenes' si, vil den producere listen over primtallene 2, 3, 5, 7.

Sigte af Eratosthenes-algoritmen

Algoritme Sieve of Eratosthenes

Her er algoritmen til Sieve of Eratosthenes:

Trin 1) Lav en liste med tal fra 2 til det givne talområde n. Vi starter med 2, fordi det er det mindste og første primtal.

Trin 2) Vælg det mindste tal på listen, x (i starten er x lig med 2), gennemgå listen, og filtrer de tilsvarende sammensatte tal ved at markere alle multipla af det valgte tal.

Trin 3) Vælg derefter det næste primtal eller det mindste umarkerede tal på listen, og gentag trin 2.

Trin 4) Gentag det forrige trin, indtil værdien af ​​x er mindre end eller lig med kvadratroden af ​​n (x <=Algoritme Sieve of Eratosthenes).

Bemærk: Den matematiske argumentation er ret simpel. Talområdet n kan faktoriseres som:

n = a * b

Igen, n = Algoritme Sieve of Eratosthenes * Algoritme Sieve of Eratosthenes

= (faktor mindre end Algoritme Sieve of Eratosthenes) * (faktor større end Sigte af Eratosthenes-algoritmen)

Så i hvert fald en af ​​de primære faktorer eller begge skal være <= Algoritme Sieve of EratosthenesDerfor, at krydse op til Algoritme Sieve of Eratosthenes vil være nok.

Trin 5) Efter disse fire trin vil de resterende umarkerede tal være alle primtallene i det givne område n.

Bearbejdet eksempel

Eksempel:

Lad os tage et eksempel og se, hvordan det fungerer.

I dette eksempel finder vi listen over primtal fra 2 til 25. Så n = 25.

Trin 1) I det første trin tager vi en liste med tal fra 2 til 25, da vi valgte n = 25.

Algoritme Sieve of Eratosthenes

Trin 2) Så vælger vi det mindste tal på listen, x. I starten er x = 2, fordi det er det mindste primtal. Så går vi gennem listen og markerer multiplaerne af 2.

Multiplarne af 2 for den givne værdi af n er: 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24.

Sigte af Eratosthenes-algoritmen

Bemærk: Blå farve angiver det valgte tal, og lyserød farve angiver de eliminerede multipla.

Trin 3) Derefter vælger vi det næstmindste umarkerede tal, som er 3, og gentager det sidste trin ved at markere multiplerne af 3.

Sigte af Eratosthenes-algoritmen

Trin 4) Vi gentager trin 3 på samme måde, indtil x = Sigte af Eratosthenes-algoritmen eller 5.

Sigte af Eratosthenes-algoritmen

Trin 5) De resterende ikke-markerede tal er primtallene fra 2 til 25.

Sigte af Eratosthenes-algoritmen

pseudoCode

Den følgende pseudokode indfanger den grundlæggende struktur af Eratosthenes-sigten, før vi oversætter den til faktisk kode.

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

Si af Eratosthenes C/C++ Code Eksempel

Nedenfor er en komplet C++ Implementering af Eratosthenes' si, der udskriver ethvert primtal op til en valgt øvre grænse.

#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;
}

Output:

2 3 5 7 11 13 17 19 23

Sigte af Eratosthener Python Program eksempel

Følgende Python Programmet implementerer den samme algoritme ved hjælp af en boolsk liste og en while-løkke.

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)

Output:

2
3
5
7
11
13
17
19
23

Segmenteret sigte

Vi har set, at Eratosthenes' si løber en løkke gennem hele talområdet. Derfor behøver den O(n) hukommelsesplads til at gemme tallene. Situationen bliver kompliceret, når vi forsøger at finde primtal i et enormt talområde, fordi det ikke er muligt at allokere en så stor hukommelsesblok til et større n.

Algoritmen kan optimeres ved at introducere nogle nye funktioner. Ideen er at opdele talområdet i mindre segmenter og beregne primtal i disse segmenter én efter én. Dette er en effektiv måde at reducere rummets kompleksitet. Denne metode kaldes en segmenteret sigte.

Optimeringen kan opnås på følgende måde:

  1. Brug en simpel sigte til at finde primtal fra 2 til Segmenteret sigte og gem dem i et array.
  2. Opdel området [0…n-1] i flere størrelsessegmenter Segmenteret sigte.
  3. For hvert segment iterer du gennem segmentet og markerer multiplerne af primtallene fundet i trin 1. Dette trin kræver O(Segmenteret sigte) maksimalt.

Den almindelige sigte kræver O(n) ekstra hukommelsesplads, hvorimod den segmenterede sigte kræver O(Segmenteret sigte), hvilket er en betydelig forbedring for et stort n. Metoden har også en ulempe, fordi den ikke forbedrer tidskompleksiteten.

Kompleksitetsanalyse

At forstå både rum- og tidskompleksitet hjælper dig med at vælge mellem den almindelige si og den segmenterede si til en given problemstørrelse.

Rumkompleksitet:

Den simple Eratosthenes-sigtealgoritme kræver O(n) hukommelsesplads. Den segmenterede sigte kræver O(Kompleksitetsanalyse) hjælperum.

Tidskompleksitet:

Tidskompleksiteten af ​​en regulær Eratosthenes-sigtealgoritme er O(n*log(log(n))). Ræsonnementet bag denne kompleksitet diskuteres nedenfor.

For et givet tal n er den tid, der kræves for at markere et sammensat tal (dvs. et ikke-primtal), konstant. Så antallet af gange løkken kører er lig med:

n/2 + n/3 + n/5 + n/7 + ……∞

= n * (1/2 + 1/3 + 1/5 + 1/7 +…….∞)

Den harmoniske progression af summen af ​​primtallene kan udledes som log(log(n)):

(1/2 + 1/3 + 1/5 + 1/7 +…….∞) = log(log(n))

Så tidskompleksiteten vil være:

T(n) = n * (1/2 + 1/3 + 1/5 + 1/7 + ……∞)

= n * log(log(n))

Således er tidskompleksiteten O(n * log(log(n))).

Dernæst vil du lære om Pascals trekant.

Ofte Stillede Spørgsmål

Ethvert sammensat tal n kan skrives som et produkt af to faktorer, og mindst én faktor skal være mindre end eller lig med kvadratroden af ​​n. Det er unødvendigt at markere multipla ud over dette punkt, fordi alle sammensatte tal allerede er elimineret.

Den almindelige si allokerer O(n) hukommelse til at markere hvert tal, mens den segmenterede si opdeler området i blokke af størrelse √n og genbruger hukommelsen. Den segmenterede version foretrækkes, når n er meget stort, og RAM er begrænset.

Den kører i O(n log log n) tid, hvilket er tæt på lineært. Det tager kun en brøkdel af et sekund at generere hvert primtal under ti millioner på en moderne bærbar computer, hvilket gør sigten til det hurtigste praktiske valg til små til mellemstore områder.

Moderne AI-acceleratorer fremskynder store prime-søgninger ved at parallelisere sigter på GPU'er og TPU'er. Maskinlæringsmodeller hjælper også med at forudsige lovende kandidatintervaller, hvilket reducerer arbejdsbyrden for Miller-Rabin og andre primality-tests, der bruges i RSA-nøglegenerering.

Ja. AI-vejledere genererer trin-for-trin tracvisualiserer sammensat eliminering, foreslår optimeringer såsom hjulfaktorisering og forklarer beviser interaktivt. De hjælper eleverne med at opbygge intuition for harmoniske seriegrænser og kompleksitetsargumenter bag sigten.

Opsummer dette indlæg med: