优化素数因子分解算法

时间:2014-04-03 04:29:16

标签: python optimization factorization

下面是一个算法,它找到给定数字N的素数因子分解。我想知道是否有任何方法可以使用巨大的数字来加快速度。我说的是20-35位数字。我想尝试让这些尽可能快。有什么想法吗?

import time

def prime_factors(n):
    """Returns all the prime factors of a positive integer"""
    factors = []
    divisor = 2        
    while n > 1:        
        while n % divisor == 0:
            factors.append(divisor)
            n /= divisor          
        divisor = divisor + 1
        if divisor*divisor > n:
            if n > 1: 
                factors.append(n)
            break
    return factors

#HUGE NUMBERS GO IN HERE!
start_time = time.time()
my_factors = prime_factors(15227063669158801)
end_time = time.time()
print my_factors
print "It took ", end_time-start_time, " seconds."

4 个答案:

答案 0 :(得分:1)

您的算法是试验分区,其时间复杂度为O(sqrt(n))。您可以通过仅使用2和奇数作为试验除数来改进算法,或者甚至更好地仅使用素数作为试验除数,但时间复杂度将保持为O(sqrt(n))。

为了更快,你需要一个更好的算法。试试这个:

def factor(n, c):
    f = lambda(x): (x*x+c) % n
    t, h, d = 2, 2, 1
    while d == 1:
        t = f(t); h = f(f(h)); d = gcd(t-h, n)
    if d == n:
        return factor(n, c+1)
    return d

要拨打您的号码,请说

print factor(15227063669158801, 1)

几乎立即返回(可能是复合的)因子2090327。它使用了一种名为 rho 算法的算法,该算法由John Pollard于1975年发明.rho算法具有时间复杂度O(sqrt(sqrt(n))),因此它比试验快得多分裂。

还有许多其他算法用于分解整数。对于您感兴趣的20到35位数范围内的数字,椭圆曲线算法非常适合。它应该在不超过几秒的时间内计算该大小的数量。另一种非常适合这种数字的算法,特别是半素数(恰好有两个素因子),是SQUFOF。

如果您对使用素数进行编程感兴趣,我会在我的博客上谦虚地推荐this essay。当你完成它之后,我博客上的其他条目将讨论椭圆曲线分解和SQUFOF,以及各种其他更强大的分解更大整数的方法。

答案 1 :(得分:0)

例如,列出数字100的所有素数因子分解。

  • 检查 2 是否是因果关系之一。然后,2&lt;可以移除2 * c <= 100。例如,4,6,8,...... 98
  • 检查 3 是否是因素之一。然后,3&lt;可以移除2 * d <= 100。例如,9,12,...... 99
  • 4 已从可能的设置中移除。
  • 检查 5 ,然后删除10,15,20,...,100。
  • 6 已删除。
  • 检查 7 ,.... ....

答案 2 :(得分:0)

似乎没有检查除数。对不起,如果我错了,但你怎么知道除数是否为素数?你的除数变量在每个循环后增加1,所以我认为它会产生很多复合数。

答案 3 :(得分:0)

对该算法的优化不允许您至少在一般情况下考虑35位数。原因是高达35位数的素数太高而无法在合理的时间内列出,更不用说尝试除以每一个。即使有人倾向于尝试,存储它们所需的位数也会太多。在这种情况下,您需要从general purpose factorization algorithms列表中选择不同的算法。

然而,如果所有素因子都足够小(比如低于10 ^ 12左右),那么你可以使用分段Sieve of Eratosthenes,或者只是找到一个实数的素数列表(例如10) ^ 12左右)在线并使用它而不是试图计算素数并希望列表足够大。

相关问题