我认为这是技术上的车轮分解。我正在尝试重新压缩我的程序对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
此外,自从我发现任何东西的渐近复杂性已经过去了几年。我很确定这是一种改进,虽然不是很大的改进。