Jak sprawdzić, czy liczba jest idealną potęgą w czasie wielomianowym

23

Pierwszym krokiem algorytmu testowania pierwotności AKS jest sprawdzenie, czy liczba wejściowa jest mocą doskonałą. Wydaje się, że jest to dobrze znany fakt w teorii liczb, ponieważ artykuł nie wyjaśnił go szczegółowo. Czy ktoś może mi powiedzieć, jak to zrobić w czasie wielomianowym? Dzięki.

yzll
źródło
7
Pierwszym krokiem algorytmu AKS jest sprawdzenie, czy numer wejściowy jest doskonała moc (liczba z formą pewnego liczb całkowitych C, N> 1), która różni się od badań, czy liczba jest liczbą pierwszą mocy. Testem na doskonałą moc jest ćwiczenie 9.44 książki cytowanej w artykule ( Modern Computer Algebra autorstwa von zur Gathen i Gerhard, 2003). Nie przeczytałem książki i nie znam odpowiedzi, ale skonsultowałeś się z nią? cn
Tsuyoshi Ito,
1
Uważam, że pierwszy krok AKS sprawdza, czy liczba jest potęgą jakiejś dodatniej liczby całkowitej, niekoniecznie liczbą pierwszą. Gdyby wiadomo było, jak sprawdzić moc pierwotną w czasie wielomianowym przed AKS, dałoby to już test wieloznaczności pierwotności czasu.
arnab 10.10.10
@Tsuyoshi Dzięki za zwrócenie uwagi na mój błąd. Nie skonsultowałem książki.
yzll,
2
Jeśli zależy Ci na pytaniu , spróbuj rozwiązać problem przed jego opublikowaniem.
Tsuyoshi Ito,
Tsuyoshi / arnab, może powinieneś repost jako odpowiedzi, aby można to zaakceptować?
Suresh Venkat

Odpowiedzi:

31

Biorąc pod uwagę liczbę n, jeśli w ogóle można go zapisać jako (b> 1), a następnie b < log ( n ) + 1 . I dla każdej ustalonej b , sprawdzenie czy istnieje A z a b = n można zrobić za pomocą wyszukiwania binarnego. Chyba całkowity czas pracy to O ( log 2 n ) .abb<log(n)+1baab=nO(log2n)

Ramprasad
źródło
5
Ramprasad za odpowiedź pomija czasie wykonać potęgowanie który . Innym sposobem jest wybór b następnie obliczyć się b th pierwiastek n , które mają całkowity czas O ( l O g 3 N ) . O(log3n)bbnO(log3n)
David Marquis
1
Poprawę prosty, że ponadto usuwa współczynnik tylko przez wybrał doskonałą b . loglognb
Chao Xu,
16

Zobacz Bach i Sorenson, Algorytmy Sieve dla doskonałego testowania mocy, Al Algorytmica 9 (1993), 313-328, DOI: 10.1007 / BF01228507 i DJ Bernstein, Wykrywanie doskonałych mocy w zasadniczo liniowym czasie, Matematyka. Komp. 67 (1998), 1253-1283.

Jeffrey Shallit
źródło
Jest też praca uzupełniająca z ulepszonym asymptotycznym czasem pracy i prostszym traktowaniem: DJ Bernstein, HW Lenstra Jr. i J. Pila, Wykrywanie doskonałych mocy poprzez uwzględnienie w matematyce. Komp. 76 (2007) 385–388.
Erick Wong,
3

W artykule znalazłem ciekawe i eleganckie rozwiązanie: o wdrożeniu testu pierwszorzędności klasy AKS, autorstwa R. Crandalla i J. Papadopoulosa, 18 marca 2003 r.

Plomb
źródło
2

Jakoś mogę pokazać, że algorytmem wyszukiwania binarnego jest .O(lg n(lg lg n)2)

Po pierwsze, , jest b < l g n . Algorytm wyszukiwania binarnego: Dla każdego b używamy wyszukiwania binarnego, aby znaleźć a .ab=nb<lg n
ba

Za każdym razem, obliczanie kosztów l g b = l g l g n operacji za pomocą szybkiej potęgowanie . Dlatego pozostałym problemem jest zakres a .ablg b=lg lg na

Jeśli jest maksymalna możliwa wartość , a następnie przeszukiwanie binarne musi l g A operacjiAalg A

Zauważ, że , to znaczy l g A = l g nb lg a=lg n Podsumowując, lgA=lgn(1

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: Wszystkie lg są podstawą 2.

Kod Python:

#--- 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
źródło