Java生成“随机”数字,不会重复2 ^ 48个周期

基本上我想生成随机数不会重复很长时间(我不想使用序列),例如java使用的LCG:

synchronized protected int next(int bits) { seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L <>> (48 - bits)); } 

据我所知,这种情况下的种子只会在2 ^ 48次调用后才重复,这是正确的吗?

所以我理解,如果我做了一个像这样的方法:

  synchronized protected long next() { seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1); return seed; } 

保证种子值在2 ^ 48次呼叫之前不重复?

不适用于那个LCG,因为每次调用时你都会被2 ^ 48修改(因此周期/状态的长度最多为2 ^ 48)。 如果你想要一个更好的随机数发生器,你可以尝试Mersenne twister:

http://en.wikipedia.org/wiki/Mersenne_twister

标准MT19937的周期为2 ^ 19937-1(!!!)这应该比您需要的更多。

作为参考, java.util.Random中实现的线性同余生成器的参数如下:

a = 25214903917 = 7 x 443 x 739 x 11003
c = 11
m = 2 48
a – 1 = 25214903916

当且仅当满足以下所有条件时 , 周期长度最多为m

  1. ✔c和m并且是相对素数

  2. ✔a – 1可被m的所有素因子整除

  3. ✔如果m是4的倍数,则a – 1是4的倍数

是的,期限是2 48 。 问题是“低阶位经历非常短的周期。” 连续值的低阶位之间的强相关性显着限制了您可以用它们做什么。

您可以使用SecureRandom作为随机替代品。 它不像Random那样快。

您可以使用Collection.shuffle() ,这可能是性能问题..

 ArrayList number = new ArrayList(); for (int i = 0; i < array.size(); ++i) number.add(i); Collections.shuffle(number);