Rabin-Miller Strong Pseudoprime Test-Implementierung nicht funktionieren
Versucht, das umzusetzen, Rabin-Miller Strong Pseudoprime Test heute.
Verwendet haben Wolfram Mathworld als Referenz, Zeilen 3-5 fasst mein code ziemlich viel.
Jedoch wenn ich das Programm starte, sagt es (manchmal), dass Primzahlen (auch niedrig wie 5, 7, 11) sind keine Primzahlen. Habe ich mich über den code für eine sehr lange Zeit und kann nicht herausfinden, was falsch ist.
Für die Hilfe ich habe mir auf dieser Website aswell als viele andere Seiten, aber die meisten verwenden eine andere definition (wahrscheinlich das gleiche, aber da bin ich neu in dieser Art von Mathematik, die ich nicht sehen kann die gleiche offensichtliche Verbindung).
Mein Code:
import random
def RabinMiller(n, k):
# obviously not prime
if n < 2 or n % 2 == 0:
return False
# special case
if n == 2:
return True
s = 0
r = n - 1
# factor n - 1 as 2^(r)*s
while r % 2 == 0:
s = s + 1
r = r // 2 # floor
# k = accuracy
for i in range(k):
a = random.randrange(1, n)
# a^(s) mod n = 1?
if pow(a, s, n) == 1:
return True
# a^(2^(j) * s) mod n = -1 mod n?
for j in range(r):
if pow(a, 2**j*s, n) == -1 % n:
return True
return False
print(RabinMiller(7, 5))
Wie unterscheidet sich dies von der gegebenen definition bei Mathworld?
- Warum muss das in Java als ein tag? Sieht aus wie Python zu mir...
- Wenn Sie mit Java, vielleicht könnte Sie uns zeigen Sie Ihre java-code zu vergleichen, um den Algorithmus.
- Sorry, es ursprünglich geschrieben in Java und dann umgeschrieben in Python machen es leichter zu Lesen. Dann, wenn ich gebucht, ich war nicht erlaubt, neues zu schaffen-tags (nicht zu sagen, Python ist ein neuer tag) und nahm einfach Java, da bin ich alles in es. Wieder einmal, sorry für dieses.
- Sie sollten
if n == 2
vor dem check für gerade zahlen, da du sonst zurückFalse
bevor Sie selbst prüfen, ob die Zahl 2. - FWIW, eine Menge von der Logik ist umgedreht hier. Die Idee hinter Rabin-Miller-ist, dass Sie testen ein paar Dinge, und wenn die Zahl eine Primzahl ist, dass Sie passieren, also, wenn Sie nicht pass, dann sind es die composite. Jetzt bist du True zurück, sobald eine Prüfung geschieht zu übergeben. Stattdessen, Sie wirklich wollen, testen Sie diese Bedingungen, und wenn Sie Versagen, dann sollten Sie False zurück, und am Ende return True (bedeutet das womöglich, prime).
- Danke für den Tipp - das ist natürlich wahr. Ich habe die Plätze getauscht auf Sie jetzt. Aber das Allgemeine problem, für n ungleich 2 (wie 7 im code) das problem bleibt immer noch.
pow(a, 2**j*s, n) == -1 % n
- Ich denke, die% n
am Ende ist überflüssig.- vergleicht man das Ergebnis der
pow
mit positiven Argumenten zu-1
(ohne Modul) ist keine gute Idee. - war nicht sicher, thx
Du musst angemeldet sein, um einen Kommentar abzugeben.
1. Kommentare in Ihrem code
Einer Anzahl der Punkte, die ich machen werde weiter unten festgestellt wurden, die in anderen Antworten, aber es scheint nützlich, um Sie alle zusammen.
Im Abschnitt
du hast die Rollen von r und s vertauscht: Sie haben tatsächlich einkalkuliert n − 1 2sr. Wenn Sie möchten, zu bleiben, um die MathWorld-notation, dann müssen Sie swap -
r
unds
in diesem Abschnitt des Codes:In der Zeile
die variable
i
ungenutzt ist: es ist üblich, Namen wie Variablen_
.Wählen Sie eine zufällige Basis zwischen 1 und n − 1 inklusive:
Dies ist, was es sagt, in dem MathWorld-Artikel, aber das Artikel ist geschrieben aus der Mathematiker-Sicht. In der Tat ist es nutzlos, um die Basis 1, da die 1s = 1 (mod n) und Sie werden Abfall-ein Versuch. Ebenso ist es nutzlos, um die Basis n − 1, da s ist ungerade und damit (n − 1)s = -1 (mod n). Mathematiker haben keine sorgen zu machen über vergebliche versuche, aber die Programmierer tun, so schreiben Sie stattdessen:
(n muss mindestens 4 für diese Optimierung zu arbeiten, aber wir können leicht arrangieren, dass durch die Rückkehr
True
an den Anfang der Funktion, wenn n = 3, genau wie für n = 2.)Wie bereits in anderen Antworten, hast du falsch verstanden, die MathWorld-Artikel. Wenn er sagt, dass "n geht der test" heißt es, dass "n besteht die Prüfung für den Basis - eine". Die Unterscheidung Tatsache über Primzahlen ist, dass Sie den test bestehen, für alle Basen. Also, wenn Sie feststellen, dass eines = 1 (mod n), was Sie tun sollten, ist zu gehen um die Schleife und wählen Sie den nächsten base zu testen, gegen.
Gibt es eine Möglichkeit für Optimierung hier. Der Wert x, dass haben wir gerade berechnet wird eine20 s (mod n). So konnten wir es gleich testen und sparen uns eine loop iteration:
In die Rubrik, wo du berechnen eine2j s (mod n) jede dieser zahlen ist das Quadrat der vorhergehenden Zahl (modulo n). Es ist verschwenderisch zu berechnen, die jeweils von Grund auf neu, wenn Sie nur könnten Platz der Vorherige Wert. Also, schreiben Sie diese Schleife als:
Ist es eine gute Idee, um zu testen, für die Teilbarkeit durch kleine Primzahlen, bevor Sie versuchen, Miller–Rabin. Zum Beispiel, in Rabin ist 1977 Papier er sagt:
2. Überarbeitete Kodex
Putting all dies zusammen:
Zusätzlich zu dem, was Omri Barel gesagt hat, gibt es auch ein problem mit der for-Schleife. Sie werden zurück
true
wenn Sie einen findena
dass der test bestanden. Jedoch, allea
haben, um den test zu bestehen, fürn
werden, die eine mögliche Primzahl ist.Ich wundere mich über dieses Stück code:
Nehmen wir
n = 7
. Son - 1 = 6
. Wir können expressn - 1
als2^1 * 3
. In diesem Fallr = 1
unds = 3
.Aber der code oben findet etwas anderes. Es beginnt mit
r = 6
, sor % 2 == 0
. Zunächsts = 0
so nach einer iteration wir habens = 1
undr = 3
. Aber jetztr % 2 != 0
und die Schleife beendet.Wir am Ende mit
s = 1
undr = 3
was eindeutig falsch:2^r * s = 8
.Sollten Sie nicht aktualisieren Sie
s
in der Schleife. Stattdessen sollten Sie zählen, wie viele Male Sie können durch 2 dividieren (dies wirdr
) und das Ergebnis nach Divisionens
. In dem Beispiel vonn = 7
,n - 1 = 6
, können wir teilen es mal (sor = 1
) und nach der Teilung, die wir am Ende mit 3 (alsos = 3
).Hier ist meine version:
Wenn Sie wissen möchten, mehr über die Programmierung mit Primzahlen, die ich bescheiden empfehlen dieser essay auf meinem blog.
Sollten Sie auch einen Blick auf Wikipedia, wo die bekannten "random" - Sequenzen gibt garantiert Antworten bis zu einer bestimmten prime.