我需要一个生成器,用于许多(最多一万亿,10 ^ 12)个独特的随机64位数字。
生成器需要按排序顺序返回数字(Long.MIN_VALUE为Long.MAX_VALUE)。问题是排序$ 10 ^ {12} $ number的速度很慢。该用例正在复制为BBHash运行的测试(在paper中,4.5索引一万亿个密钥)。
直接的解决方案是在内存中创建一个集合,使用大量的集合
确保不会返回重复项。
但是这会占用太多内存或I / O.
我想最多使用几MB内部状态。
生成器应该在内部使用java.util.Random。
它应该是"公平"尽可能(具有相同的统计分布,如果否则生成)。我还希望有一个128位数字版本(2长)。
到目前为止我所拥有的是在内存中创建一个集合的代码(Java代码):
public static void main(String... args) {
for(long x : randomSet(10, 0)) {
System.out.println(x);
}
}
static Iterable randomSet(int size, int seed) {
Random r = new Random(seed);
TreeSet set = new TreeSet();
while (set.size() < size) {
set.add(r.nextLong());
}
return set;
}
-8292973307042192125
-7423979211207825555
-6688467811848818630
-4962768465676381896
-2228689144322150137
-1083761183081836303
-279624296851435688
4437113781045784766
6146794652083548235
7105486291024734541
最简单(错误)的解决方案是非随机的,是均匀分配结果。
我不认为解决方案会随着时间的推移添加一个随机的差距&#34;将工作,
因为它很慢,10 ^ 12之后这些间隙的总和不会降落到它应该的位置(好吧,也许:记住剩下多少个数,然后重新计算分布......)。我认为以下内容应该有效,但是很复杂,并且不确定要使用哪些公式:对于每个位级别,
递归地,计算可能发生多少0/1
(以某种方式使用二项分布或近似,正态/高斯分布)。
在某些时候停止(例如,100万条或更少的区块),
使用上面的代码,以获得速度。
但也许有一个优雅的解决方案。
也许这与Metropolis-Hastings算法有关,不确定。
我读了&#34;一种有效的顺序随机抽样算法&#34;,
但我认为这只适用于小n,我发现很难从中获得一个简单的算法。
Java代码是最好的,但C很好(无论如何,我可能必须将其转换为C / C ++)。我想不要使用太多的库来简化移植。