Das Sieb des Eratosthenes in Python & C++

⚡ Intelligente Zusammenfassung

Das Sieb des Eratosthenes ist ein klassischer Primzahlalgorithmus, der zusammengesetzte Zahlen filtert, indem er iterativ Vielfache jeder Primzahl markiert und so nur Primzahlen innerhalb einer gewählten Obergrenze für die schnelle Suche übrig lässt.

  • 🔢 Kernidee: Markiere Vielfache jeder Primzahl, beginnend mit 2, um Primzahlen bis n zu isolieren.
  • 🧮 Schleifenbeschränkung: Iteriere nur bis zur Quadratwurzel von n, da größere Faktoren bereits eliminiert wurden.
  • Zeitliche Komplexität: Der Algorithmus hat eine Laufzeit von O(n log log n), was für praktische Bereiche nahezu linear ist.
  • Segmentiertes Sieb: Durch die Aufteilung des Bereichs in Blöcke reduziert sich der Hilfsspeicher von O(n) auf O(√n).
  • 🧪 Anwendungsfälle: Kryptographie, Hashing, Wettbewerbsprogrammierung und Zahlentheorie basieren auf der schnellen Generierung von Primzahlen.

Das Sieb des Eratosthenes in Python

Was ist das Sieb des Eratosthenes?

Das Sieb des Eratosthenes ist das einfachste Primzahlsieb. Es ist ein Algorithmus, mit dem man alle Primzahlen innerhalb einer vorgegebenen Grenze finden kann. Es existieren mehrere Primzahlsiebe, darunter das Sieb des Eratosthenes, das Sieb von Atkin und das Sieb von Sundaram.

Das Wort "Sieb„“ bezeichnet ein Utensil, das Substanzen filtert. In diesem Sinne ist der Siebalgorithmus in Python und anderen Sprachen bezieht sich auf eine Methode, die Primzahlen aus einer Liste von ganzen Zahlen herausfiltert.

Dieser Algorithmus filtert Primzahlen iterativ. Der Filterprozess beginnt mit der kleinsten Primzahl. Eine Primzahl ist eine natürliche Zahl größer als 1, die nur zwei Teiler hat, nämlich 1 und sich selbst. Numbers Zahlen, die keine Primzahlen sind, werden zusammengesetzte Zahlen genannt.

Warum das Sieb des Eratosthenes verwenden?

Beim Sieb des Eratosthenes wird zunächst eine kleine Primzahl ausgewählt und anschließend alle Vielfachen davon herausgefiltert. Dieser Vorgang wird in einer Schleife über einen vorgegebenen Bereich wiederholt und liefert so effizient alle Primzahlen bis n, ohne für jede Zahl eine Probedivision durchzuführen.

Dadurch ist das Sieb schneller als die Primzahlprüfung für jede Zahl einzeln. Es findet breite Anwendung in der Zahlentheorie, Kryptographie, beim Hashing und im Wettbewerbsprogrammieren, wo viele Primzahlen schnell generiert werden müssen.

Beispielsweise:

Nehmen wir den Zahlenbereich von 2 bis 10.

Sieb des Eratosthenes-Algorithmus

Nach Anwendung des Siebs des Eratosthenes erhält man die Liste der Primzahlen 2, 3, 5, 7.

Sieb des Eratosthenes-Algorithmus

Algorithmus-Sieb von Eratosthenes

Hier ist der Algorithmus für das Sieb des Eratosthenes:

Schritt 1) Erstelle eine Liste von Zahlen von 2 bis zum angegebenen Bereich n. Wir beginnen mit 2, weil es die kleinste und erste Primzahl ist.

Schritt 2) Wähle die kleinste Zahl in der Liste, x (anfangs ist x gleich 2), durchlaufe die Liste und filtere die entsprechenden zusammengesetzten Zahlen, indem du alle Vielfachen der ausgewählten Zahl markierst.

Schritt 3) Wählen Sie dann die nächste Primzahl oder die kleinste nicht markierte Zahl in der Liste und wiederholen Sie Schritt 2.

Schritt 4) Wiederhole den vorherigen Schritt, bis der Wert von x kleiner oder gleich der Quadratwurzel von n ist (x <= 0).Algorithmus-Sieb von Eratosthenes).

Hinweis: Die mathematische Begründung ist recht einfach. Der Zahlenbereich n lässt sich wie folgt faktorisieren:

n = a * b

Auch hier ist n = Algorithmus-Sieb von Eratosthenes * Algorithmus-Sieb von Eratosthenes

= (Faktor kleiner als Algorithmus-Sieb von Eratosthenes) * (Faktor größer als Sieb des Eratosthenes-Algorithmus)

Also mindestens einer der Primfaktoren oder beide müssen <= sein Algorithmus-Sieb von EratosthenesDaher durchquert man bis zu Algorithmus-Sieb von Eratosthenes wird genug sein.

Schritt 5) Nach diesen vier Schritten sind die verbleibenden unmarkierten Zahlen alle Primzahlen in diesem gegebenen Bereich n.

Ausgearbeitetes Beispiel

Ejemplo:

Nehmen wir ein Beispiel und sehen wir uns an, wie es funktioniert.

In diesem Beispiel ermitteln wir die Liste der Primzahlen von 2 bis 25. Also ist n = 25.

Schritt 1) Im ersten Schritt nehmen wir eine Liste von Zahlen von 2 bis 25, da wir n = 25 gewählt haben.

Algorithmus-Sieb von Eratosthenes

Schritt 2) Dann wählen wir die kleinste Zahl der Liste, x. Zunächst ist x = 2, da dies die kleinste Primzahl ist. Anschließend durchlaufen wir die Liste und markieren alle Vielfachen von 2.

Die Vielfachen von 2 für den gegebenen Wert von n sind: 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24.

Sieb des Eratosthenes-Algorithmus

Hinweis: Die Farbe Blau kennzeichnet die ausgewählte Zahl, die Farbe Rosa die ausgeschlossenen Vielfachen.

Schritt 3) Dann wählen wir die nächstkleinere nicht markierte Zahl, also 3, und wiederholen den letzten Schritt, indem wir die Vielfachen von 3 markieren.

Sieb des Eratosthenes-Algorithmus

Schritt 4) Wir wiederholen Schritt 3 auf die gleiche Weise, bis x = Sieb des Eratosthenes-Algorithmus oder 5.

Sieb des Eratosthenes-Algorithmus

Schritt 5) Die übrigen nicht markierten Zahlen sind die Primzahlen von 2 bis 25.

Sieb des Eratosthenes-Algorithmus

Pseudo-Code

Der folgende Pseudocode erfasst die Grundstruktur des Siebs des Eratosthenes, bevor wir ihn in tatsächlichen Code übersetzen.

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

Sieb des Eratosthenes C/C++ Code Beispiel

Nachfolgend finden Sie eine vollständige C++ Implementierung des Siebs des Eratosthenes, das alle Primzahlen bis zu einer gewählten oberen Grenze ausgibt.

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

Ausgang:

2 3 5 7 11 13 17 19 23

Sieb von Eratosthenes Python Programmbeispiel

Folgende Python Das Programm implementiert denselben Algorithmus mithilfe einer booleschen Liste und einer while-Schleife.

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)

Ausgang:

2
3
5
7
11
13
17
19
23

Segmentiertes Sieb

Wir haben gesehen, dass das Sieb des Eratosthenes den gesamten Zahlenbereich durchläuft. Daher benötigt es O(n) Speicherplatz, um die Zahlen zu speichern. Die Situation wird kompliziert, wenn wir Primzahlen in einem sehr großen Bereich suchen, da es nicht praktikabel ist, für ein größeres n einen so großen Speicherblock zu reservieren.

Der Algorithmus kann durch die Einführung einiger neuer Funktionen optimiert werden. Die Idee besteht darin, den Zahlenbereich in kleinere Segmente aufzuteilen und die Primzahlen in diesen Segmenten einzeln zu berechnen. Dies ist eine effiziente Möglichkeit, die Speicherkomplexität zu reduzieren. Diese Methode wird als segmentiertes Sieb.

Die Optimierung kann auf folgende Weise erreicht werden:

  1. Verwenden Sie ein einfaches Sieb, um Primzahlen von 2 bis zu finden Segmentiertes Sieb und speichern Sie sie in einem Array.
  2. Teilen Sie den Bereich [0…n-1] in höchstens mehrere Segmente der Größe auf Segmentiertes Sieb.
  3. Für jedes Segment wird das Segment durchlaufen und die Vielfachen der in Schritt 1 gefundenen Primzahlen markiert. Dieser Schritt benötigt O(Segmentiertes Sieb) maximal.

Das reguläre Sieb benötigt O(n) zusätzlichen Speicherplatz, während das segmentierte Sieb O(Segmentiertes Sieb), was für ein großes n eine deutliche Verbesserung darstellt. Die Methode hat jedoch auch einen Nachteil, da sie die Zeitkomplexität nicht verbessert.

Komplexitätsanalyse

Das Verständnis sowohl der räumlichen als auch der zeitlichen Komplexität hilft Ihnen bei der Auswahl zwischen dem regulären Sieb und dem segmentierten Sieb für eine gegebene Problemgröße.

Raumkomplexität:

Der einfache Sieb-Algorithmus des Eratosthenes benötigt O(n) Speicherplatz. Der segmentierte Sieb-Algorithmus benötigt O(Komplexitätsanalyse) Hilfsraum.

Zeitliche Komplexität:

Die Zeitkomplexität eines regulären Sieb-des-Eratosthenes-Algorithmus beträgt O(n*log(log(n))). Die Gründe für diese Komplexität werden im Folgenden erläutert.

Für eine gegebene Zahl n ist die Zeit, die zum Markieren einer zusammengesetzten Zahl (d. h. einer Nicht-Primzahl) benötigt wird, konstant. Daher entspricht die Anzahl der Schleifendurchläufe:

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

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

Die harmonische Folge der Summe der Primzahlen lässt sich wie folgt herleiten: log(log(n)):

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

Die Zeitkomplexität beträgt also:

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

= n * log(log(n))

Die Zeitkomplexität beträgt somit O(n * log(log(n))).

Als Nächstes erfahren Sie mehr über Pascals Dreieck.

Häufig gestellte Fragen

Jede zusammengesetzte Zahl n kann als Produkt zweier Faktoren geschrieben werden, wobei mindestens ein Faktor kleiner oder gleich der Quadratwurzel von n sein muss. Das Kennzeichnen weiterer Vielfacher ist unnötig, da alle zusammengesetzten Zahlen bereits ausgeschlossen sind.

Das reguläre Siebverfahren benötigt O(n) Speicherplatz, um jede Zahl zu markieren, während das segmentierte Siebverfahren den Bereich in Blöcke der Größe √n unterteilt und Speicherplatz wiederverwendet. Die segmentierte Variante ist vorzuziehen, wenn n sehr groß und der Arbeitsspeicher begrenzt ist.

Die Laufzeit beträgt O(n log log n), was nahezu linear ist. Die Generierung aller Primzahlen unter zehn Millionen dauert auf einem modernen Laptop nur einen Bruchteil einer Sekunde, wodurch das Siebverfahren die schnellste praktikable Wahl für kleine bis mittlere Bereiche darstellt.

Moderne KI-Beschleuniger beschleunigen umfangreiche Primzahlsuchen durch die Parallelisierung von Sieben auf GPUs und TPUs. Modelle des maschinellen Lernens helfen zudem bei der Vorhersage vielversprechender Kandidatenbereiche und reduzieren so den Arbeitsaufwand für Miller-Rabin- und andere Primzahltests, die bei der RSA-Schlüsselerzeugung verwendet werden.

Ja. KI-Tutoren generieren Schritt-für-Schritt-Anleitungen. tracSie visualisieren zusammengesetzte Elimination, schlagen Optimierungen wie die Radfaktorisierung vor und erklären Beweise interaktiv. Sie helfen Lernenden, ein intuitives Verständnis für Schranken harmonischer Reihen und Komplexitätsargumente hinter dem Sieb zu entwickeln.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: