在Java中生成数百万个非重复随机数

时间:2011-05-01 07:56:48

标签: java random

我有一个问题,我可以用什么算法在Java中生成一组2 ^ 21个随机唯一数字? java中是否有另一个库生成随机数而不是math.random?

提前致谢!

3 个答案:

答案 0 :(得分:2)

查看Apache Commons Math API随机包http://commons.apache.org/math/userguide/random.html

答案 1 :(得分:2)

关键问题是你用“数字”来表达什么?

一般来说,这个问题可以通过'生成一个数字列表,将其按随机顺序排列,取其中的前2 ^ 21个'来解决。 第一部分是微不足道的 第二部分可以通过fisher yates算法来解决 真正的问题是如果你想使用一个非常大的数字空间。那你需要一个懒惰的解决方案

这是我要做的: 使用数据结构来表示外观看起来像数组的列表,但内部使用基于散列表的稀疏数组表示来表示。此外,如果在尝试从单元格中读取时,如果您没有在散列中点击某些内容,只需返回该单元格的索引。

对于index变量,您修改后的渔民停留在2 ^ 21,并在j和数组的“长度”(整数)之间使用随机变量index < / p>

这种惰性方法在O(n)时间和O(n)空间中生成任意类型的随机非重复列表,其中n是您尝试生成的数组的长度。这是你能做的最好的事情。

有关Fisher-Yates的解释http://en.wikipedia.org/wiki/Fisher-Yates_shuffle

答案 2 :(得分:0)

您可以使用Format-Preserving Encryption加密计数器。你的计数器从0开始向上,加密使用你选择的一个键将它变成一个看似随机的值,无论你想要什么基数和宽度。

分组密码通常具有固定的块大小,例如, 64或128位。但格式保留加密允许你采用像AES这样的标准密码,并制作一个小宽度的密码,无论你需要什么基数和宽度(例如基数2,问题参数的宽度21),算法仍然是密码学上强大。

保证永远不会发生冲突(因为加密算法会创建1:1映射)。它也是可逆的(双向映射),因此您可以获取结果数字并返回到您开始时的计数器值。

AES-FFX是一种提出标准的方法来实现这一目标。