
(
Abbildung Quelle )
Es ist bekannt, dass das Sieb des Eratosthenes (RE) einer der ältesten Algorithmen ist, die lange vor der Erfindung der Computer erschienen sind. Daher könnte man denken, dass dieser Algorithmus im Laufe der Jahrhunderte auf und ab untersucht wurde und nichts hinzugefügt werden kann. Wenn Sie sich Wikipedia ansehen, gibt es ein Meer von Verweisen auf maßgebliche Quellen, in denen Sie leicht ertrinken können. Daher war ich überrascht, als ich neulich versehentlich entdeckte, dass die
Option , die auf Wikipedia als optimal dargestellt wird, erheblich optimiert werden kann.
Es war so. In einer Diskussion eines Artikels über funktionale Programmierung (FP) stellte er eine
Frage : Wie schreibe ich RE in diesem Paradigma? Ich habe mehr als nur geringe Kenntnisse über AF und wage es nicht, die Antworten zu beurteilen, aber andere Diskussionsteilnehmer lehnten einige der vorgeschlagenen Lösungen sofort ab, was darauf hinweist, dass anstelle der theoretischen Komplexität
O(n log logn) (1)Die vorgeschlagene Implementierung wird rechenintensiv sein
O(n2/ logn) (2)und dass Sie bei dieser Komplexität nicht warten können, wenn beispielsweise 10 Millionen Nummern gesiebt werden. Ich wurde interessiert und versuchte, die optimale Version gemäß Wikipedia mit der üblichen prozeduralen Programmierung zu implementieren. In Delphi-7 habe ich den folgenden Code erhalten:
Listing 1program EratosthenesSieve;
RE wird durch das Boolesche Siebarray mit inversen Werten dargestellt. Wenn die Zahl eine Primzahl ist, wird sie als falsch angezeigt, wodurch die Anzahl der Negationsoperationen (nicht) während des Siebens verringert wird. Das Programm enthält drei Verfahren: Initialisierung des RE-Init, Berechnungen (Durchsuchen und Durchstreichen von Zahlen im RE) - Berechnen und Drucken der als Ergebnis gefundenen Primzahlen - Drucken und Zählen der Anzahl der gefundenen Zahlen. Ich werde besonders auf die auskommentierte Ausgabe von Primzahlen im Druckverfahren hinweisen: Zum Testen bei N = 1000 wird der Kommentar entfernt.
Hier in der Berechnungsprozedur verwende ich die Wikipedia-Empfehlung: Löschen Sie für die nächste Primzahl i Zahlen aus dem RE
i2,i2+i,i2+2i,...
Dieses Programm hat in 17,6 Sekunden eine Milliarde Zahlen durchgesehen. auf meinem PC (3,4 GHz Intel Core i7 CPU).
Nachdem ich dieses Programm erstellt hatte, erinnerte ich mich plötzlich an die bekannten Eigenschaften von
geraden und ungeraden Zahlen .
Lemma 1. 1) ungerade + ungerade = gerade; 2) ungerade + gerade = ungerade; 3) gerade + gerade = gerade.Beweis1)
(2n+1)+(2m+1)=2n+2m+2 teilbar durch 2. TCD.
2)
(2n+1)+(2m)=2n+2m+1 ohne Rest nicht durch 2 teilbar. Chtd.
3)
(2n)+(2m)=2n+2m teilbar durch 2. TCD.
Lemma 2. Das Quadrat einer ungeraden Zahl ist eine ungerade Zahl.Beweis. (2n+1)2=4n2+4n+1 ohne Rest nicht durch 2 teilbar. Chtd.
Bemerkung. Eine Primzahl größer als 2 ist ungerade.Daher können Sie nur ungerade Zahlen löschen:
i2,i2+2i,i2+4i,... (3)Aber zuerst müssen Sie alle geraden Zahlen streichen. Dies erfolgt durch eine modifizierte Initialisierungsinitialisierungsprozedur.
Listing 2: program EratosthenesSieve;
Dieses Programm arbeitete 9,9 Sekunden lang. - Fast doppelt so schnell.
Um die Entsprechung des Echtzeit-Programmbetriebs mit der Theorie zu beurteilen, schlug ich dies vor
dt=C∗O,
wo
dt - gemessene Betriebszeit;
C - konstant mit der Dimension der Zeit;
O - theoretische Bewertung.
Von hier aus berechnet
C zu bewerten (1) und (2). Für
N=106 und weniger
dt nahe Null. Deshalb bringe ich die Daten auf das erste Programm für große
N.Wie wir sehen, liegt die Schätzung (1) viel näher an den tatsächlichen Ergebnissen. Für das zweite Programm wird ein ähnliches Bild beobachtet. Ich bezweifle sehr, dass ich Amerika mithilfe der Sequenz (3) entdeckt habe, und ich werde sehr dankbar sein für die Verknüpfung mit der Arbeit, in der dieser Ansatz angewendet wurde. Höchstwahrscheinlich sind die Wikipedia-Autoren selbst in einem Meer von Informationen über den elektronischen Krieg ertrunken und haben diese Arbeit verpasst.
PS Für den Wikipedia-Algorithmus mit "linearer Laufzeit"
siehe