如何检查数字是否是多项式时间的完美幂


23

AKS素数测试算法的第一步是检查输入数字是否为完美幂。这似乎是数论中众所周知的事实,因为本文没有详细解释。有人可以告诉我如何在多项式时间内执行此操作吗?谢谢。


7
AKS算法的第一步是测试输入数字是否为理想幂(对于某些整数c,n> 1,形式为的数字),这与测试数字是否为质数幂不同。测试完美功率的方法是该论文引用的练习9.44(von zur Gathen和Gerhard着的Modern Computer Algebra,2003年)。我没有读过这本书,也不知道答案,但是您已经阅读了这本书吗?cn
伊藤刚(Tsuyoshi Ito)2010年

1
我相信AKS的第一步是检查数字是否是某个正整数的幂,不一定是质数。如果知道如何在AKS之前的多项式时间内检查素数,那早就可以得到一个多项式时间素数测试仪。
arnab

@Tsuyoshi感谢您指出我的错误。我没有看过这本书。
yzll

2
如果您关心这个问题,请在发布前尝试解决问题。
伊藤刚(Tsuyoshi Ito)2010年

Tsuyoshi / arnab,也许您应该重新发布答案,这样才能被接受?
Suresh Venkat 2010年

Answers:


31

给定一个数n,如果在所有它可写为(B> 1),则b < 日志Ñ + 1。而对于每一个固定的b,检查是否存在一个一个一个b = ñ可以使用二进制搜索来完成。因此,我估计总运行时间为O log 2 n abb<log(n)+1baab=nO(log2n)


5
兰普拉萨德的答案不包括进行求幂的时间,即。另一种方法是选择b,然后计算n的b个根,其总时间为O l o g 3 n O(log3n)bbnO(log3n)
大卫·马奎斯

1
一个简单的改进,通过仅选择素数b进一步消除了因子。loglognb
赵超

16

参见Bach和Sorenson,《用于完美功率测试的Sieve算法》,Algorithmica 9(1993),313-328,DOI:10.1007 / BF01228507,和DJ Bernstein,《在基本上线性的时间内检测完美功率》,《数学》。比较 67(1998),1253-1283。


还有一篇后续文章,它改善了渐近运行时间并简化了处理过程:DJ Bernstein,HW Lenstra Jr.和J. Pila,通过分解为互质数来检测完美幂,Math。比较 76(2007),385-388。
Erick Wong

3

我在论文中找到了一个有趣而优雅的解决方案:关于AKS类素数测试的实现,R.Crandall和J.Papadopoulos,2003年3月18日。


2

不知何故,我可以表明,该二进制搜索算法是O(lg n(lg lg n)2)

首先,,存在b < l g n二进制搜索算法: 对于每个b,我们使用二进制搜索找到aab=nb<lg n
ba

每次使用快速幂运算来计算花费l g b = l g l g n个运算 。因此,剩下的问题是范围ablg b=lg lg na

如果是最大可能值,那么二进制搜索需要 操作Aalg A

注意,即 l g A = l g nb lg a=lg n 。当总结, Σ=Ñ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:所有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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.