具有与质数数量成比例的数据的主筛的空间复杂性是多少?

时间:2014-10-20 09:54:41

标签: python primes space-complexity sieve sieve-of-atkin

我练习编写针对空间或时间复杂度进行优化的算法。使用优质筛,至少您必须存储所有找到的素数列表。似乎与发现的素数成比例的数据是这种算法可能使用的最小空间量。

  • 这个理由有效吗?
  • 如何评估此算法的空间复杂度?

From Wikipedia about the sieve of Atkin - 我不确定的是,当素数超过此值时,筛子如何使用O(n ^ 1/2)空间。这就是为什么它似乎至少必须与质数的数量成比例。我是否将可数数字与空间复杂性混为一谈?

In this paper on the sieve of Atkin,他们的算法打印"素数高达N ...这里“记忆”不包括打印机使用的纸张。"这似乎是对空间的不公平计算。

  • 我希望澄清这应该如何/实际上是客观地测量的。
def prime_sieve(limit):
    factors = dict()
    primes = []
    factors[4] = (2)
    primes.append(2)
    for n in range(3, limit + 1):
        if n not in factors:
            factors[n * 2] = (n)
            primes.append(n)
        else:
            prime = factors.get(n)
            m = n + prime
            while m in factors:
                m += prime
            factors[m] = (prime)
            del factors[n]
    return primes

3 个答案:

答案 0 :(得分:2)

此算法的空间复杂度为len(numbers) + len(primes);列表的大小加上字典的大小。

在这种情况下,算法更糟比你期望的天真素数筛(limit)。 len(numbers) + len(primes) > limit因为例如对于prime_sieve(100),以下不相关的数字存储在numbers

{129: 43, 134: 67, 141: 47, 142: 71, 146: 73, 158: 79, 166: 83, 178: 89, 194: 97, 102: 17, 104: 2, 105: 3, 106: 53, 110: 11, 111: 37, 112: 7, 114: 19, 115: 23, 116: 29, 117: 13, 118: 59, 120: 5, 122: 61, 123: 41, 124: 31}

有几种素数筛,具有不同的时间和空间复杂性;见例如Wikipedia以及How do i reduce the space complexity in Sieve of Eratosthenes to generate prime between a and b?

等问题

另请注意,prime = numbers.get(n)没有必要 - 您已经检查了if n not in numbers,因此您只需使用prime = numbers[n]

答案 1 :(得分:1)

空间复杂度测量非常公平。如果将primes.append(n)替换为yield n,并在消费者例程中逐个处理素数而不将它们全部存储,例如查找具有特定属性的素数,则需要存储空间素数本身是O(1),以素数的数量来衡量。

yield是构建生成器的Python方式,这是一种协同例程,它向调用者发出值并保存函数的状态,以便它可以重新生成输入。)

答案 2 :(得分:1)

  

“使用优质筛子,至少你必须存储所有找到的素数列表。”

不正确的。您只需要在下限(包括)上限的平方根下面的素数,以筛选该范围内的素数。

如果您的筛子是增量的,无限制的,那么您只需要在当前生产点的平方根下面(并包括)填充。

怎么可能?通过为“核心”质数(低于sqrt的那些)使用单独的素数供应,完全可以使用相同的函数计算 - 递归。有关示例,请参阅this answer

不计算生产的素数是完全合法的 - 你可以确实将它们发送到打印机或外部文件等等。因此,这种筛子的空间复杂性将是{{ 1}}对于 n 素数达到 N~ = n * log n

另外,不要靠近阿特金的筛子。街上的一句话是,用它来击败Eratosthenes的正确轮式筛子是不可能的(通过GordonBGood搜索关于这个主题的答案,如this one)。< / p>