Como verificar se um número é uma potência perfeita em tempo polinomial

23

A primeira etapa do algoritmo de teste de primalidade AKS é verificar se o número de entrada é uma potência perfeita. Parece que esse é um fato bem conhecido na teoria dos números, uma vez que o artigo não a explicou em detalhes. Alguém pode me dizer como fazer isso em tempo polinomial? Obrigado.

yzll
fonte
7
A primeira etapa do algoritmo AKS é testar se o número de entrada é uma potência perfeita (um número do formato para alguns números inteiros c, n> 1), que é diferente de testar se o número é uma potência principal. O teste para uma potência perfeita é o Exercício 9.44 do livro citado no artigo ( Álgebra de Computador Moderna de von zur Gathen e Gerhard, 2003). Não li o livro e não sei a resposta, mas você consultou o livro? cn
Tsuyoshi Ito 10/10
1
Acredito que o primeiro passo do AKS verifica se o número é uma potência de um número inteiro positivo, não necessariamente um primo. Se soubesse como verificar uma potência principal em tempo polinomial antes da AKS, isso já teria fornecido um testador de primalidade por tempo polinomial.
Arnab
@ Tsuyoshi Obrigado por apontar meu erro. Eu não consultei o livro.
yzll
2
Se você se importa com a pergunta , tente resolver o problema antes de publicá-la.
Tsuyoshi Ito 10/10
Tsuyoshi / arnab, talvez você deva repassar como respostas para que isso possa ser aceito?
Suresh Venkat

Respostas:

31

Dado um número n, se é que pode ser escrito como (b> 1), então . E para cada fixo , é possível verificar se existe um com usando pesquisa binária. O tempo total de execução é, portanto, eu acho. b < log ( n ) + 1 b a a b = n O ( log 2 n )abb<log(n)+1baab=nO(log2n)

Ramprasad
fonte
5
Folhas de resposta do Ramprasad o tempo para fazer a exponenciação que é . Outra maneira é a de escolher b , em seguida, calcular a b th raiz de n que terá um tempo total de S ( l S g 3 n ) . O(log3n)bbnO(log3n)
David Marquis
1
Uma melhoria simples que remove ainda mais um fator de , escolhendo apenas prime b . loglognb
Chao Xu
16

Veja Bach e Sorenson, algoritmos de peneira para teste de potência perfeita, Algorithmica 9 (1993), 313-328, DOI: 10.1007 / BF01228507, e DJ Bernstein, Detectando potências perfeitas em tempo essencialmente linear, Math. Comp. 67 (1998), 1253-1283.

Jeffrey Shallit
fonte
Há também um artigo de acompanhamento com tempo de execução assintótico aprimorado e tratamento mais simples: DJ Bernstein, HW Lenstra Jr. e J. Pila, Detectando poderes perfeitos considerando os coprimes, Math. Comp. 76 (2007), 385-388.
precisa saber é o seguinte
3

Encontrei uma solução interessante e elegante no artigo: Sobre a implementação do teste de primalidade da classe AKS, por R.Crandall e J.Padadopoulos, 18 de março de 2003.

Plomb
fonte
2

De alguma forma, posso mostrar que o algoritmo de busca binária é .O(lg n(lg lg n)2)

Primeiramente, , existe b < l g n . Algoritmo de pesquisa binária: Para cada b , usamos a pesquisa binária para encontrar a .ab=nb<lg n
ba

Cada vez que o cálculo de custa l g b = l g l g n operações usando exponenciação rápida . Portanto, o problema restante é o intervalo de a .ablg b=lg lg na

Se é o valor máximo possível de a , a pesquisa binária precisa de operações l g AAalg A

Observe que , ou seja, l g A = l g nb lg a=lg n Ao resumir, lgA=lgn(1

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

Em outras palavras, todas as operações para pesquisa binária são O(lg nlg lg n)

abO(lg n(lg lg n)2)

ps: Todos os lg são base 2.

Código 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
fonte