数値が多項式時間で完全なべき乗であるかどうかを確認する方法


23

AKS素数性テストアルゴリズムの最初のステップは、入力数が完全なべき乗かどうかを確認することです。論文では詳細に説明されていないため、これは数論でよく知られている事実のようです。誰かが多項式時間でこれを行う方法を教えてもらえますか?ありがとう。


7
AKSアルゴリズムの最初のステップは、入力数が完全な累乗(一部の整数c、n> 1に対する形式の数)であるかどうかをテストすることです。これは、数が素数であるかどうかのテストとは異なります。完全な力のテストは、論文で引用された本の演習9.44です(von zur Gathen and GerhardによるModern Computer Algebra、2003年)。私は本を​​読んでおらず、答えも知りませんが、あなたは本を調べましたか?cn
伊藤剛

1
AKSの最初のステップでは、数値が必ずしも素数ではなく、正の整数の累乗であるかどうかをチェックします。AKSの前に多項式時間で素数のべき乗をチェックする方法がわかっていれば、それはすでに多項式時間の素数テスタを与えていたでしょう。
arnab

@Tsuyoshi私の間違いを指摘してくれてありがとう。私は本を​​参照していません。
yzll

2
質問が気になる場合、投稿する前に問題を解決してください。
伊藤剛

剛/ arnab、これを受け入れられるように答えとして再投稿する必要がありますか?
スレシュヴェンカト

回答:


31

数nが与えられたとしてもそれがa b(b> 1)と書くことができるなら、b < log n + 1です。そしてすべての固定のためにBが存在する場合、検査ABは = N二分探索を使用して行うことができます。したがって、合計実行時間はO log 2 n です。abb<log(n)+1baab=nO(log2n)


5
Ramprasadの答えは、あるべき乗を行う時間を省きます。もう1つの方法は、bを選択し、nのb番目のルートを計算することです。このルートの合計時間はO l o g 3 n )になります。O(log3n)bbnO(log3n)
デビッドマーキス

1
素数bを選択するだけで因子をさらに削除する単純な改善。loglognb
チャオシュー

16

Bach and Sorenson、Sieve algorithm for perfect power testing、Algorithmica 9(1993)、313-328、DOI:10.1007 / BF01228507、およびDJ Bernstein、Detecting perfect powers in本質的に線形時間、Math。比較 67(1998)、1253-1283。


漸近的な実行時間を改善し、処理を簡素化したフォローアップペーパーもあります。DJBernstein、HW Lenstra Jr.、およびJ. Pila、コプリムに因数分解して完全な力を検出、Math。比較 76(2007)、385–388。
エリックウォン14年

3

R.CrandallとJ.Papadopoulosによる、2003年3月18日のAKSクラスの素数性テストの実装に関する興味深いエレガントな解決策を見つけました。


2

O(lg n(lg lg n)2)

ab=nb<lg n
ba

ablg b=lg lg na

Aalg 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:lgはすべて基数2です。

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.