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

时间:2011-06-24 04:39:21

标签: java random

基本上我想生成随机数,这些数字在很长一段时间内都不会重复(我不想使用序列),例如java使用的LCG:

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

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

所以我理解,如果我做了一个像:

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

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

4 个答案:

答案 0 :(得分:8)

供参考,linear congruential generator中实施的java.util.Random参数如下:

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

当且仅当以下所有为真时,period length最多 m

  1. c m 并且是relatively prime

  2. a - 1可被 m 的所有素数因子整除

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

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

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:1)

您可以使用SecureRandom代替随机替换。它的重复速度不如Random。

答案 3 :(得分:1)

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

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