52

这是我使用种子作为参数生成随机数的代码:

double randomGenerator(long seed) {
    Random generator = new Random(seed);
    double num = generator.nextDouble() * (0.5);

    return num;
}

每次我给一个种子并尝试生成 100 个数字时,它们都是一样的。
我怎样才能解决这个问题?

4

7 回答 7

84

如果你给的是相同的种子,那是正常的。这是允许测试的重要功能。

检查此项以了解伪随机生成和种子:

伪随机数发生器

伪随机数生成器 (PRNG),也称为确定性随机位生成器 DRBG,是一种用于生成近似随机数属性的数字序列的算法。该序列不是真正随机的,因为它完全由一组相对较小的初始值决定,称为 PRNG 的状态,其中包括一个真正的随机种子。

如果你想有不同的序列(不调整或调试算法时的常见情况),你应该调用零参数构造函数,它使用 nanoTime 来尝试每次获取不同的种子。这个Random实例当然应该保留在您的方法之外。

你的代码应该是这样的:

private Random generator = new Random();
double randomGenerator() {
    return generator.nextDouble()*0.5;
}
于 2012-09-17T11:38:56.580 回答
35

简单的方法是使用:

Random rand = new Random(System.currentTimeMillis());

Random这是生成数字的最佳方式。

于 2016-03-29T09:55:40.473 回答
11

您不应该在方法范围内创建新的 Random 。使其成为类成员:

public class Foo {
   private Random random 

   public Foo() {
       this(System.currentTimeMillis());
   }

   public Foo(long seed) {
       this.random = new Random(seed);
   }

   public synchronized double getNext() {
        return generator.nextDouble();
   }
}

这只是一个例子。我不认为Random以这种方式包装会增加任何价值。把它放在你正在使用它的班级中。

于 2012-09-17T11:44:25.480 回答
7

这就是Pseudo -RNG 的原理。这些数字并不是真正随机的。它们是使用确定性算法生成的,但根据种子的不同,生成数字的顺序会有所不同。因为你总是使用相同的种子,所以你总是得到相同的序列。

于 2012-09-17T11:38:47.513 回答
2

问题是您再次播种随机生成器。每次播种时,随机数生成器的初始状态都会被重置,并且您生成的第一个随机数将是初始状态之后的第一个随机数

于 2012-09-17T11:38:56.343 回答
1

如果您想使用一个种子生成多个数字,您可以执行以下操作:

public double[] GenerateNumbers(long seed, int amount) {
    double[] randomList = new double[amount];
    for (int i=0;i<amount;i++) {
        Random generator = new Random(seed);
        randomList[i] = Math.abs((double) (generator.nextLong() % 0.001) * 10000);
        seed--;
    }
    return randomList;
}

如果您使用相同的种子,它将显示相同的列表。

于 2015-10-23T10:02:24.373 回答
1

这里的几个示例创建了一个新Random实例,但这是不必要的。也没有理由synchronized像一种解决方案那样使用。相反,利用ThreadLocalRandom类上的方法:

double randomGenerator() {
    return ThreadLocalRandom.current().nextDouble(0.5);
}
于 2017-04-25T15:06:32.160 回答