So prüfen Sie, ob eine Zahl in der Polynomzeit eine perfekte Potenz ist

23

Der erste Schritt des AKS-Primalitätstest-Algorithmus besteht darin, zu überprüfen, ob die eingegebene Zahl eine perfekte Potenz ist. Es scheint, dass dies in der Zahlentheorie eine bekannte Tatsache ist, da das Papier es nicht im Detail erklärte. Kann mir jemand sagen, wie man das in polynomialer Zeit macht? Vielen Dank.

yzll
quelle
7
Der erste Schritt des AKS-Algorithmus besteht darin, zu prüfen, ob die eingegebene Zahl eine perfekte Potenz ist (eine Zahl der Form für einige ganze Zahlen c, n> 1), die sich von der Prüfung unterscheidet, ob die Zahl eine Primzahl ist. Der Test für eine perfekte Kraft ist Aufgabe 9.44 des in der Arbeit zitierten Buches ( Moderne Computeralgebra von von zur Gathen und Gerhard, 2003). Ich habe das Buch nicht gelesen und kenne die Antwort nicht, aber Sie haben das Buch konsultiert? cn
Tsuyoshi Ito
1
Ich glaube, der erste Schritt von AKS prüft, ob die Zahl eine Potenz einer positiven ganzen Zahl ist, nicht unbedingt eine Primzahl. Wenn es bekannt wäre, wie man eine Primzahl in der Polynomzeit vor AKS prüft, hätte dies bereits einen Polynomzeit-Primalitätstester gegeben.
Arnab
@ Tsuyoshi Danke für den Hinweis auf meinen Fehler. Ich habe das Buch nicht gelesen.
yzll
2
Wenn Ihnen die Frage am Herzen liegt, versuchen Sie bitte, das Problem zu lösen, bevor Sie es veröffentlichen.
Tsuyoshi Ito
Tsuyoshi / Arnab, vielleicht solltest du als Antwort erneut posten, damit dies akzeptiert werden kann?
Suresh Venkat

Antworten:

31

Bei einer Zahl n, wenn überhaupt kann sie geschrieben werden als (b> 1), dann b < log ( n ) + 1 . Und für jedes feste b kann mit der binären Suche geprüft werden, ob ein a mit a b = n existiert . Die Gesamtlaufzeit ist daher O ( log 2 n ), denke ich.abb<Log(n)+1beineinb=nO(Log2n)

Ramprasad
quelle
5
Ramprasads Antwort lässt die Zeit aus, um die Exponentiation durchzuführen, die . Eine andere Möglichkeit besteht darin, b zu wählen und dann die b- te Wurzel von n zu berechnen, die eine Gesamtzeit von O ( l o g 3 n ) hätte . O(log3n)bbnO(log3n)
David Marquis
1
Eine einfache Verbesserung, die einen -Faktor weiter entfernt , indem nur Primzahl b ausgewählt wird . loglognb
Chao Xu
16

Siehe Bach und Sorenson, Sieve algorithms for perfect power testing, Algorithmica 9 (1993), 313-328, DOI: 10.1007 / BF01228507, und DJ Bernstein, Detecting perfect powers in im Wesentlichen linear time, Math. Comp. 67 (1998), 1253 & ndash; 1283.

Jeffrey Shallit
quelle
Es gibt auch ein Folgepapier mit einer verbesserten asymptotischen Laufzeit und einer einfacheren Behandlung: DJ Bernstein, HW Lenstra Jr. und J. Pila, Detecting perfect powers by factoring in coprimes, Math. Comp. 76 (2007), 385–388.
Erick Wong
3

In der Arbeit habe ich eine interessante und elegante Lösung gefunden: Über die Implementierung des AKS-Klassenprimalitätstests von R.Crandall und J.Papadopoulos, 18. März 2003.

Plomb
quelle
2

Irgendwie kann ich zeigen, dass der binäre Suchalgorithmus .O(lg n(lg lg n)2)

Erstens ist , es gibt b < l g n . Algorithmus für binäre Suche: Für jedes b verwenden wir die binäre Suche, um a zu finden .ab=nb<lg n
ba

Jedes Mal, wenn die Berechnung von unter Verwendung einer schnellen Exponentiation Operationen mit l g b = l g l g n kostet . Das verbleibende Problem ist daher die Reichweite von a .ablg b=lg lg na

Wenn der maximal mögliche Wert von a ist , benötigt die binäre Suche l g A -OperationenAalg A

b lg a=lg n

lg A=lg nb
lg A=lg n(11+12+...+1B)=lg nlg B=lg nlg lg n

O(lg nlg lg n)

abO(lg n(lg lg n)2)

ps: Alle lg sind Basis 2.

Python-Code:

#--- a^n ---------------------------------------
def fast_exponentation(a, n):
    ans = 1
    while n:
        if n & 1 : ans = ans * a
        a = a * a
        n >>= 1
    return ans
#------------------------------------------
# Determines whether n is a power a ^ b, O(lg n (lg lg n) ^ 2)
def is_power(n):
    if (- n & n) == n: return True  # 2 ^ k
    lgn = 1 + ( len( bin ( abs ( n ) ) ) - 2)
    for b in range(2,lgn):
        # b lg a = lg n
        lowa = 1L
        higha = 1L << (lgn / b + 1)
        while lowa < higha - 1:
            mida = (lowa + higha) >> 1
            ab = fast_exponentation(mida,b) 
            if ab > n:   higha = mida
            elif ab < n: lowa  = mida
            else:   return True # mida ^ b
    return False
Kevin
quelle