Java Random.nextInt(int)在设置不同种子时返回相同的值

时间:2016-07-14 13:50:20

标签: java random seed

我编写了一个测试java.util.Random的演示版,我希望生成相同5个数字的重复列表,但是在设置不同种子时我得到相同的值。在我的程序中,种子的范围从0到4。据我所知,不同的种子产生不同的值,同一种子获得相同的价值。所以我认为结果将是相同5个数字的重复列表。但实际值输出都是一样的。我的代码出了什么问题?谁能告诉我?

import java.util.Random;

public class Main {
    public Main() {
    }

    public static void main(String[] args) {
        for (int i = 0 ; i <= 255; i++)
        {
            String hex = Integer.toHexString(randInt(0, 255, i % 5));
            System.out.println(hex);
        }
    }
    private static Random rand = new Random();
    public static int randInt(int min, int max, long seed) {
        rand.setSeed(seed);
        System.out.println("seed:" + seed);
        int randomNum = rand.nextInt((max - min) + 1) + min;
        return randomNum;
    }
}

结果是:

seed:0
bb
seed:1
bb
seed:2
bb
seed:3
bb
seed:4
bb
seed:0
bb
seed:1
bb
seed:2
bb
seed:3
bb
seed:4
bb
seed:0
bb
seed:1
bb
seed:2
bb
seed:3
bb
seed:4
bb
seed:0
bb
seed:1
...
...
...

2 个答案:

答案 0 :(得分:3)

  

据我所知,不同的种子产生不同的价值

这是不正确的,不同的种子可能产生不同的值,它们也可以产生相同的值。

有2 ^ 64种可能的种子,rand.nextInt(256)只能返回256个不同的值,因此许多种子必须返回相同的值。

同样是setSeed javadoc状态

  

类Random的setSeed实现恰好只使用48   给定种子的位

因此,如果您的种子仅在忽略的位中有所不同,则所有值都是相同的。

答案 1 :(得分:0)

我在grepcode上找到了这个实现,有一个if语句来检测n是2的幂。如果n(即绑定)是2的幂(int)((n * (long)next(31)) >> 31);被使用。< / p>

public int nextInt(int n) {
    if (n <= 0)
         throw new IllegalArgumentException("n must be positive");
    if ((n & -n) == n)  // i.e., n is a power of 2
        return (int)((n * (long)next(31)) >> 31);
    int bits, val;
    do {
        bits = next(31);
        val = bits % n;
    } while (bits - val + (n-1) < 0);
    return val;
}

我不知道你的JDK中是否使用了这个实现,但是这表明2边界的功能被区别对待。

  

该算法特别处理n为2的幂的情况:它从底层伪随机数生成器返回正确数量的高阶位。在没有特殊处理的情况下,将返回正确数量的低位。已知诸如由该类实现的线性同余伪随机数发生器在其低阶位的值序列中具有短周期。因此,如果n是2的小幂,这种特殊情况极大地增加了连续调用此方法返回的值序列的长度。