【问题标题】:Python more memory efficient object than set for subtractionPython比减法设置的内存效率更高的对象
【发布时间】:2016-01-12 19:05:51
【问题描述】:

我正在尝试编写一个函数,该函数可以使用Sieve of Eratosthenes 找到某个非常大的数之下的所有素数。我写了函数:

def primes(limit):
    #efficient method for finding large primes
    l=set()
    i=1
    while i<limit+1:
        l.add(i)
        i+=2
    s=int(math.sqrt(limit))
    #recur until sqrt is small
    if s<=1000:
        ps=smallprimes(s)
    else:
        ps=primes(s)

    for p in ps:
        l-=set(multiples(p,limit+1)[1:])
    return [2]+(list(l)[1:])

其中 smallprimes 仅通过检查因子的数量来计算低于限制的素数,而 multiples 计算低于限制的数字的所有倍数。

将非常大的限制传递给primes,我创建了大集合以“删除”limits 平方根以下所有素数的倍数。

有没有比使用集合更有效的方法从序列中“删除”数字?我想知道因为我真的只需要减去两个数组,我不需要防止重复等。

【问题讨论】:

  • 旁注:Python 不适合高效的算术运算。我建议使用一些外部库或其他语言。
  • 在我看来不像埃拉托烯的筛子,也看看这个帖子,这可能是你要找的how-to-implement-an-efficient-infinite-generator-of-prime-numbers-in-python
  • 这是一个erastothenes的筛子,我计算平方根,然后减去所有低于限制的素数的所有倍数的集合。不过,我会看看那个链接。
  • 你是否计算平方根不是我在你的算法中看到的问题,是你使用递归,你不需要它来实现这个筛子,无论如何你需要的是我给你的链接中的erat3算法,经过一些修改,它会给你所有的素数,直到N并使用最少的内存,与素数的数量成正比,直到N的平方根
  • @LukeTaylor 是的,numpy 很好。底层算法是用 C 语言编写的,所以你很高兴。

标签: python python-2.7 memory primes


【解决方案1】:

对于大型数据集使用集合会出现问题,因为哈希冲突的数量会显着增加,此外还会产生不必要的存储开销。

另一种解决方案是使用numpy 掩码数组。数组中的索引是数字,值表示它是否是素数。您可以通过将数字设置为 2 * index + 1 来进一步优化,以便您只存储奇数。

这只是一个例子。使用大筛子的集合将非常低效。

【讨论】:

  • “对于大型数据集使用集合会出现问题,因为哈希冲突的数量会显着增加” - 并非如此。当然,存在生日悖论,但导致的碰撞次数并不是真正的问题。大集合在元素数量导致冲突问题之前耗尽内存。
  • @user2357112 这实际上取决于底层的哈希函数。我不确定 Python 使用什么,但我猜你的陈述可能是非常正确的。
  • 很公平。这并不能否定我的观点,即集合可能不是做到这一点的最佳方式。这个答案只是一种选择的例子。我实际上投票结束了基于意见的问题。
  • @freakish:这是散列函数的问题,而不是大集合的问题。基于散列冲突的 DOS 攻击可以用相当小的散列表来执行,如果你的散列函数在没有攻击者参与的情况下导致大集合中的大量冲突,那么你只有一个 真的 糟糕的哈希函数。
猜你喜欢
  • 2013-03-27
  • 1970-01-01
  • 2023-03-11
  • 2021-02-10
  • 2017-09-24
  • 2020-06-18
  • 2012-02-24
  • 1970-01-01
  • 2020-07-28
相关资源
最近更新 更多