Enthält ein Standard-Python-Modul eine Funktion zum Berechnen der modularen multiplikativen Inversen einer Zahl, dh einer y = invmod(x, p)
solchen Zahl x*y == 1 (mod p)
? Google scheint hierzu keine guten Hinweise zu geben.
Natürlich kann man sich einen selbst gebrauten 10-Liner mit erweitertem euklidischen Algorithmus einfallen lassen , aber warum das Rad neu erfinden?
Zum Beispiel hat Java BigInteger
eine modInverse
Methode. Hat Python nicht etwas Ähnliches?
pow
Funktion für Folgendes verwenden :y = pow(x, -1, p)
. Siehe bugs.python.org/issue36027 . Es dauerte nur 8,5 Jahre von der Frage bis zu einer Lösung in der Standardbibliothek!Antworten:
Vielleicht findet jemand dies nützlich (aus Wikibooks ):
quelle
sympy
, dannx, _, g = sympy.numbers.igcdex(a, m)
macht der Trick.Wenn Ihr Modul prim ist (Sie nennen es
p
), können Sie einfach berechnen:Oder in Python:
Hier ist jemand, der einige Funktionen der Zahlentheorie in Python implementiert hat: http://www.math.umbc.edu/~campbell/Computers/Python/numbthy.html
Hier ist ein Beispiel an der Eingabeaufforderung:
quelle
Vielleicht möchten Sie sich auch das gmpy- Modul ansehen . Es ist eine Schnittstelle zwischen Python und der GMP-Bibliothek mit mehrfacher Genauigkeit. gmpy bietet eine Invertierungsfunktion, die genau das tut, was Sie brauchen:
Antwort aktualisiert
Wie von @hyh angegeben,
gmpy.invert()
gibt die 0 zurück, wenn die Umkehrung nicht existiert. Das entspricht dem Verhalten der GMP-mpz_invert()
Funktion.gmpy.divm(a, b, m)
bietet eine allgemeine Lösung füra=bx (mod m)
.divm()
gibt eine Lösung zurück, wenngcd(b,m) == 1
und löst eine Ausnahme aus, wenn die multiplikative Inverse nicht existiert.Haftungsausschluss: Ich bin der aktuelle Betreuer der gmpy-Bibliothek.
Aktualisierte Antwort 2
gmpy2 löst jetzt ordnungsgemäß eine Ausnahme aus, wenn die Umkehrung nicht vorhanden ist:
quelle
gmpy.invert(0,5) = mpz(0)
anstatt einen Fehlergmpy
Paket? (dh eine Funktion, die den gleichen Wert hat, aber schneller als(a * b)% p
?)(a * b) % p
in einer Funktion zu berechnen, ist nicht schneller als nur(a * b) % p
in Python auszuwerten . Der Aufwand für einen Funktionsaufruf ist höher als die Kosten für die Auswertung des Ausdrucks. Weitere Informationen finden Sie unter code.google.com/p/gmpy/issues/detail?id=61 .Ab 3.8 Python kann die pow () -Funktion einen Modul und eine negative ganze Zahl annehmen. Siehe hier . Ihr Fall für die Verwendung ist
quelle
Hier ist ein Einzeiler für CodeFights ; Es ist eine der kürzesten Lösungen:
Es wird zurückgegeben,
-1
wennA
keine multiplikative Inverse in vorhanden istn
.Verwendung:
Die Lösung verwendet den erweiterten euklidischen Algorithmus .
quelle
Sympy , ein Python-Modul für symbolische Mathematik, verfügt über eine integrierte modulare Umkehrfunktion, wenn Sie keine eigene implementieren möchten (oder wenn Sie Sympy bereits verwenden):
Dies scheint nicht auf der Sympy-Website dokumentiert zu sein, aber hier ist die Dokumentzeichenfolge: Sympy mod_inverse docstring auf Github
quelle
Hier ist mein Code, er mag schlampig sein, aber er scheint trotzdem für mich zu funktionieren.
quelle
Der obige Code läuft nicht in Python3 und ist im Vergleich zu den GCD-Varianten weniger effizient. Dieser Code ist jedoch sehr transparent. Es hat mich veranlasst, eine kompaktere Version zu erstellen:
quelle
n == 7
. Aber ansonsten ist es ungefähr gleichwertig mit diesem "Algorithmus":for i in range(2, n): if i * a % n == 1: return i
Hier ist ein prägnanter 1-Liner, der dies ohne Verwendung externer Bibliotheken tut.
Beachten Sie, dass dies wirklich nur egcd ist und optimiert wurde, um nur den einzelnen interessierenden Koeffizienten zurückzugeben.
quelle
Um die modulare multiplikative Inverse herauszufinden, empfehle ich die Verwendung des erweiterten euklidischen Algorithmus wie folgt:
quelle
a = prevX - quotient * X
sollte seinX = prevX - quotient * X
, und es sollte zurückkehrenprevX
. FWIW, diese Implementierung ähnelt der in Qaz 'Link im Kommentar zu Märt Bakhoffs Antwort.Ich probiere verschiedene Lösungen aus diesem Thread aus und am Ende benutze ich diese:
Modular_inverse in Python
quelle
return
in egcd ist falschNun, ich habe keine Funktion in Python, aber ich habe eine Funktion in C, die Sie leicht in Python konvertieren können. In der folgenden c-Funktion wird der erweiterte Euklidian-Algorithmus verwendet, um den inversen Mod zu berechnen.
Python-Funktion
Der Verweis auf die obige C-Funktion wird aus dem folgenden Link- C-Programm entnommen , um die modulare multiplikative Inverse zweier relativ Primzahlen zu finden
quelle
von der CPython Implementierung Quellcode :
Gemäß dem Kommentar über diesem Code kann er kleine negative Werte zurückgeben, sodass Sie möglicherweise prüfen können, ob er negativ ist, und n hinzufügen können, wenn er negativ ist, bevor Sie b zurückgeben.
quelle
Viele der oben genannten Links sind zum 23.01.2017 defekt. Ich habe diese Implementierung gefunden: https://courses.csail.mit.edu/6.857/2016/files/ffield.py
quelle