在Eratosthenes的筛子中反转一个功能

时间:2017-08-27 09:30:22

标签: sieve-of-eratosthenes inverse wheel-factorization

我认为这是技术上的车轮分解。我正在尝试重新压缩我的程序对Eratosthenes筛选的表示,它只包含可能是素数的数字索引。

一些背景知识:

最基本的轮子是[2]:跟踪2作为第一个素数,筛子只包含奇数索引。 (50%))

下一轮是[2 3]:跟踪两个和三个作为第一个素数,并且筛子仅包含2 * 3 = 6(即1和5)之间的间隙。索引的形式为6k + 1和6k + 5。 (33%)

下一轮是[2 3 5]:跟踪2,3和5作为第一个素数,筛子只需要8位来表示大小为30的间隔。(27%)

当清除数字的倍数时,我会使用此循环找到这些倍数:

def multiplesIndices (self, i):
    for gap in self.gaps[1:]:
        ret = i * (self.product * 0 + gap)
        if ret > len (self): break
            yield ret
    for k in xrange (1, len (self) / i / self.product + 1):
        for gap in self.gaps:
            ret = i * (self.product * k + gap)
            if ret > len (self): break
            yield ret

问题在于设置车轮所需的时间,以及压缩比的递减收益。那么,改变到不同的车轮尺寸需要进行大量的重新计算。此外,通过改变车轮尺寸,我认为我可以影响渐近复杂度。

所以我提出的解决方案是使用小轮子来初始化更大的轮子: [2 3](6/2)获得[2 3 5](30/8)轮的间隙 [2 3 5]以获得[2 3 5 7](210/48)轮的间隙

我需要帮助的地方是将已经计算好的小筛子映射到待计算的大筛子,这样我就可以避免从1开始重新筛选所有的东西。获得前30个素数,用它们找到下一个210- 30个素数,用它们来寻找下一个480-210素数。

更具体地说,我需要帮助反转此函数(或正确实现invIndexOf()):

def indexOf (self, n):
    if not self.isValidIndex (n): raise Exception ()
    ret = n / self.product * len (self.gaps) + self.gaps.index (n % self.product)
    assert n in self.invIndexOf (ret)
    return ret

此外,自从我发现任何东西的渐近复杂性已经过去了几年。我很确定这是一种改进,虽然不是很大的改进。

0 个答案:

没有答案