这是根据从序列中的一个数字到下一个数字的间隔生成汉明数字序列(又名regular numbers,5-smooth numbers)的稍微不同的方法。这是所述间隔的示例图:
因此,存在相对有限数量的离散间隔将一个数字与下一个数字分开,并且随着H增加,间隔变小。人们常常注意到,汉明数字随着尺寸的增加而变得越来越稀疏,这是绝对意义上的,但在另一种意义上(按比例)他们会更接近。
基本上,当H上升时,2 ^ i * 3 ^ j * 5 ^ k的机会更大,其中i,j,k是正整数或负整数,导致分数接近1.0。
原来只有119个区间(i,j,k三元组)的表格涵盖汉明数字,最多约10 ^ 10000。这是关于前1.59万亿汉明数字。这样的表(C头文件)按从小到大的间隔大小排序,是here。给定汉明数,找到下一个所需要的是找到表中的第一个条目,其中乘法(相应指数的加法)将产生具有i,j和k的正幂的结果。
例如,第百万汉明数是2 ^ 55 * 3 ^ 47 * 5 ^ 64,约为5.1931278e83。之后的下一个汉明数是2 ^ 38 * 3 ^ 109 * 5 ^ 29或约5.1938179e83。第一个合适的表条目是:{ - 17,62,-35},// 1.000132901540844
因此,虽然这些数字相隔约7e79,但它们的比率为1.000132901540844。要查找下一个需要在最坏情况下尝试最多119个条目的数字,只需要添加和比较(无乘法)。此外,每个条目只有3个短整数的表需要1kb以下的内存。该算法在内存中基本为O(1),在时间上基本为O(n),其中n是序列的长度。
加速它的一种方法是不是每次都从第0个索引中搜索表,而是约束表条目列表以搜索那些在经验上已知在给定范围内成功获得给定条目的条目( n <1.59e12)。这些列表在succtab []结构中的头文件中给出,例如:
{11 {47,55,58,65,66,68,70,72,73,75,76}},
因此,根据经验发现特定索引后面只列出了11个不同的索引,因此这些索引是唯一被搜索的索引。
这样做可以将算法加速4倍左右,实现here(C代码)以及上面的header file。这是i7-2600 3.4GHz机器上执行时间的图表:
我认为这与现有技术水平相比是有利的 - 是吗?
汉明问题有时会减少到只找到第n个汉明数而不产生所有中间值。将上述技术改编为一个众所周知的方案,只需枚举所需范围内的汉明数字,就可得出这段执行时间:
因此,只需不到2秒即可找到1.59万亿分之一的汉明号码。它的C代码是here。这是否也与现有技术相比有利,至少在给定的范围内?
编辑:基于特定的机器选择n(1.59e12,汉明数最多约10 ^ 10000)的界限,其中期望i,j,k是短的并且对执行速度也是合理的期望。可以生成更大的表,例如一个包含200个条目的表将允许n高达约1e18(汉明数最多约10 ^ 85000)。另一个问题是如何进一步加快速度。一个潜在的领域:事实证明,某些表项比其他表项更频繁地被击中,并且它们具有相应更大的后续列表以进行检查。例如,在生成第一个1.59e12数字时,此条目完全被46%的迭代命中:
{ - 7470,2791,1312}
它有23种不同的后继者。也许根据其他参数(例如,之前的参赛作品的历史记录)缩小范围的方法会有所帮助,尽管不会有太多的昂贵操作空间。
编辑#2:
关于生成表的一些信息,基本上有六类分数2 ^ i * 3 ^ j * 5 ^ k其中i,j,k是正整数或负整数:只有2,3或5的分数分子,分母中只有2,3或5的分数。例如,对于分子中只有2的类:
f = 2 ^ i /(3 ^ j * 5 ^ k),i> 0和j,k> = 0
计算此类分数的区间的C程序是here。对于最大约10 ^ 10000的汉明数字,它会在几秒钟内运行。它可能会变得更有效率。
对其他5类馏分重复类似的过程会产生六个列表。按间隔大小对它们进行排序并删除重复项会产生完整的表格。
答案 0 :(得分:0)
三元组枚举是 ~n 2/3 但是条带的分类是 ~n 2/3 log( n 2/3 )即 ~n 2/3 log n 。即使使用 ~n 1/3 波段空间方案,这显然也不会改变。
实际上,经验复杂性在实践中被视为 ~n 0.7 。
我还没有完全理解你的算法,但是the evidence you presented强烈建议纯 ~n 2/3 操作,这将构成 a绝对显着改善超过以前的技术水平,绝对是。
在我看来,如果需要生成整个序列以找到算法所基于的“间隔”(比率),那就不是这样了。但是,由于你独立生成它们,正如你后来的编辑所暗示的那样,它根本没有障碍。
更正:如果我们只对序列的 n 成员感兴趣,那么就不需要完整的乐队类型;确实存在 O(n) select-kth-largest 算法。