In den Kommentaren zu einem der vorherigen
Beiträge über das Sieb von Eratosthenes wurde dieser kurze Algorithmus aus
Wikipedia erwähnt:
Algorithmus 1:1: i := 2, 3, 4, ..., n: 2: lp[i] = 0: 3: lp[i] := i 4: pr[] += {i} 5: p pr p ≤ lp[i] p*i ≤ n: 6: lp[p*i] := p : lp - n pr - n.
Der Algorithmus ist einfach, aber nicht für alle schien es offensichtlich. Das Hauptproblem ist, dass es auf Wikipedia keine Beweise gibt und der
Link zur Quelle (
pdf ) einen anderen Algorithmus als den oben genannten enthält.
In diesem Beitrag werde ich hoffentlich versuchen zu beweisen, dass dieser Algorithmus nicht nur funktioniert, sondern auch für die lineare Komplexität.
Ein Hinweis zur Komplexität des AlgorithmusObwohl dieser Algorithmus asymptotisch schneller ist als das Standardsieb
von Eratosthenes in O (n log log n), benötigt er viel mehr Speicher. Daher ist es für wirklich großes n nicht anwendbar, wo immer dieser Algorithmus in seiner ganzen Pracht erstrahlt. Es ist jedoch auch für kleine n sehr nützlich, wenn Sie nicht nur alle Primzahlen finden müssen, sondern auch schnell alle Zahlen bis zu n faktorisieren müssen.
Definitionen
m a t h c a l P. - viele Primzahlen.
l p ( x ) - minimaler Primteiler einer Zahl:
lp (x) = min \ {p \ in \ mathcal {P} \ \ vert \ p \ vert x \}lp (x) = min \ {p \ in \ mathcal {P} \ \ vert \ p \ vert x \}rd(x) - andere Faktoren:
rd(x)=x/lp(x)Bitte beachten Sie, dass alle obigen Definitionen für sind
x ge2 .
Einige offensichtliche Eigenschaften der oben eingeführten Funktionen, die später verwendet werden:
lp(a malb)=min(lp(a),lp(b))rd(x)<xp in mathcalP=>lp(p)=pBeweis
Lemma 1 :
lp(x) lelp(rd(x)), forallx notin mathcalP,x>1Beweis : Weil jeder Teiler
rd(x) auch ein Teiler
x und
lp(x) keinem Divisor überlegen
x dann
lp(x) überschreitet keinen Teiler
rd(x) einschließlich der kleinsten von ihnen. Das einzige Problem mit dieser Aussage ist wenn
rd(x) hat keine einfachen Teiler, aber dies ist nur in möglich
x in mathcalP , was im Zustand des Lemmas ausgeschlossen ist.
squareLass
E = \ {(lp (x), rd (x)) \ vert \ forall x \ notin \ mathcal {P}, 2 \ le x \ le n \}Weil
lp(x) timesrd(x)=x (per Definition
rd() ), wenn wir viel bekommen hätten
E dann könnten wir rechnen
lp() für alle zusammengesetzten Zahlen bis n. Dies geschieht beispielsweise durch den folgenden Algorithmus:
Algorithmus 2: 1: (l,r) E: 2: lp[l*r] := l;
Beachten Sie das
vertE vert len Daher funktioniert der obige Algorithmus 2 für die lineare Komplexität.
Außerdem werde ich beweisen, dass Algorithmus 1 aus Wikipedia tatsächlich nur alle Elemente dieses Satzes durchläuft, da er auf andere Weise parametrisiert werden kann.
Lass
E '= \ {(p, r) \ vert p \ in \ mathcal {P}, 2 \ le r <n, p \ le lp (r), p \ mal r \ le n \}Lemma 2 :
E=E′Beweis :
Lass
(a,b) inE =>
existiertx notin mathcalP, 2 lex len mida=lp(x),b=rd(x) .
Per Definition
lp(),rd() ::
a in mathcalP ,
a timesb=x . Von Lemma 1,
a lelp(b) .
weil
rd(x)<x dann
b<n .
Seit
x notin mathcalP ,
b ge2 .
Auch per Definition
E ,
x len deshalb
a timesb len .
Alle 4 Bedingungen
E′ erfüllte Mittel
(a,b) inE′ =>
E TeilmengeE′ .
Lass
(a,b) inE′ . Lass
x=a timesb .
Per Definition
E′ ,
a in mathcalP . Mittel
a - einfache Teilung
x .
lp(x)=lp(a malb)=min(lp(a),lp(b))=min(a,lp(b)).Weil
a lelp(b) dann
lp(x)=a. Mittel
b=rd(x).Per Definition
x=a timesb len. Auch offensichtlich
x=a timesb ge2.Alle Bedingungen für
E abgeschlossen =>
E′ TeilmengeE.Deshalb
E=E′. squareJetzt bleibt es, die richtigen zu sortieren
r und
p aus der Definition der Menge
E′ und wende Algorithmus 2 an. Genau das macht Algorithmus 1 (nur die Variable i wird anstelle von r verwendet). Aber es gibt ein Problem! Alle Elemente einer Menge sortieren
E′ zu berechnen
lp, wir müssen es wissen
lp, weil es eine Bedingung in der Definition gibt
p lelp(r) .
Glücklicherweise umgeht dieses Problem die richtige Sortierreihenfolge. Es ist notwendig zu sortieren
r in der äußeren Schleife und
p - im Inneren. Dann
lp(r) wird bereits berechnet. Diese Tatsache wird durch den folgenden Satz bewiesen.
Satz 1:Algorithmus 1 unterstützt die folgende Invariante: Nach der Iteration der äußeren Schleife für i = k werden alle Primzahlen bis einschließlich k in pr hervorgehoben. Wird auch gezählt
lp() für alle
x notin mathcalP midx len, rd(x) lek im lp-Array.
Beweis :
Wir beweisen durch Induktion. Für k = 2 wird die Invariante manuell überprüft. Die einzige Primzahl 2 wird zur PR-Liste hinzugefügt, da das Array lp [] anfänglich mit Nullen gefüllt ist. Auch die einzige zusammengesetzte Nummer, in der
rd(x) le2 Ist 4. Es ist leicht zu überprüfen, ob die innere Schleife genau einmal ausgeführt wird (für n> 3) und lp [4] korrekt ausführt: = 2.
Nehmen wir nun an, dass die Invariante für die Iteration i = k-1 gilt. Beweisen wir, dass es auch für die Iteration i = k gilt.
Um dies zu tun, reicht es aus zu überprüfen, ob die Zahl i, wenn sie eine Primzahl ist, zur Liste pr hinzugefügt wird und dass
lp() wird für alle zusammengesetzten Zahlen gezählt
x len, einschließlich
rd(x)=i. Es sind diese Zahlen aus der Invariante für k, die nicht bereits von der Invariante für k-1 abgedeckt sind.
Wenn i einfach ist, ist lp [i] 0, da die einzige Schreiboperation in das Array lp, die theoretisch lp [i] (in Zeile 6) berechnen könnte, immer in zusammengesetzte Indizes schreibt, weil p * i (für i>) 1) - immer zusammengesetzt. Daher wird die Nummer i zur Liste der Primzahlen hinzugefügt. Außerdem wird in Zeile 3 lp [i] gezählt.
Wenn i zusammengesetzt ist, wird zu Beginn der Iteration lp [i] bereits durch die Invariante für i = k-1 berechnet, weil
rd(i)<i oder
rd(i) lei−1, Daher fällt ich in der vorherigen Iteration unter die invariante Bedingung. Daher wird die zusammengesetzte Zahl i nicht zur Liste der Primzahlen hinzugefügt.
Wenn das richtige lp [i] und alle Primzahlen bis einschließlich i vorhanden sind, wird die Schleife in den Zeilen 5-6 alle Elemente durchlaufen
(p,i) inE′ in dem der zweite Teil ist i:
- p inP, weil es aus der Liste pr ist
- p lelp(i), durch Bedingung zum Stoppen des Zyklus
- p timesi len, durch Bedingung zum Stoppen des Zyklus
- i<n, folgt aus p timesi len, p>1
Alle notwendigen Primzahlen in der PR-Liste sind, weil nur Zahlen bis zu
lp(i) lei . Daher werden lp [] -Werte für alle zusammengesetzten Zahlen berechnet
x für welche
rd(x)=i . Dies sind genau alle Zahlen, die beim Übergang von der Invariante für k-1 zur Invariante für k fehlten.
Daher gilt die Invariante für jedes i = 2..n.
squareDurch die Invariante aus Satz 1 für i = n stellt sich heraus, dass alle Primzahlen bis n und alle lp [] durch Algorithmus 1 berechnet werden.
Darüber hinaus werden in den Zeilen 5-6 verschiedene Elemente der Menge sortiert
E , dann wird die gesamte innere Schleife nicht mehr ausgeführt
vertE vert<n Operationen. Die Überprüfungsoperation in der Schleife läuft reibungslos ab
vertE vert+n−1<2n Zeiten (
vertE vert times gibt true zurück und n-1 times geben für jedes i false zurück. Alle verbleibenden Operationen sind in einem Zyklus in i von 2 bis n verschachtelt.
Daraus folgt, dass die Komplexität von Algorithmus 1 O (n) ist.