使用种子的Java随机数

使用种子的Java随机数,java,random,seed,Java,Random,Seed,这是我使用种子作为参数生成随机数的代码: double randomGenerator(long seed) { Random generator = new Random(seed); double num = generator.nextDouble() * (0.5); return num; } 每次我给一个种子并尝试生成100个数字时,它们都是一样的。 如何解决这个问题?这是伪RNG的原理。这些数字并不是随机的。它们是使用确定性算法生成的,但根据种子的不同,

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

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

    return num;
}
每次我给一个种子并尝试生成100个数字时,它们都是一样的。

如何解决这个问题?

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

问题是您再次为随机生成器种子。每次为其设定种子时,随机数生成器的初始状态将被重置,并且生成的第一个随机数将是初始状态后的第一个随机数

如果给定相同的种子,这是正常的。这是允许测试的一个重要特性

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

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

如果您想拥有不同的序列(通常情况下不调优或调试算法),则应调用零参数构造函数,该构造函数使用nanoTime每次尝试获取不同的种子。这个
Random
实例当然应该在您的方法之外

您的代码可能如下所示:

private Random generator = new Random();
double randomGenerator() {
    return generator.nextDouble()*0.5;
}
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;
}

您不应该在方法范围内创建新的随机变量。使其成为班级成员:

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
会增加任何价值。把它放在你正在使用它的类中

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

private Random generator = new Random();
double randomGenerator() {
    return generator.nextDouble()*0.5;
}
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;
}
public double[]GenerateNumbers(长种子,整数数量){
double[]随机列表=新的double[金额];

对于(int i=0;i而言,简单的方法是使用:

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

这是生成
随机
数字的最佳方法。

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


这就是种子应该做的。你只为一个种子生成一个数字。你想实现什么?你可以使用
System.currentTimeMillis()
作为产生随机结果的种子。不提供任何种子也会产生随机结果。我不确定如果你不提供任何种子,它是否会在某个时候开始重复。这个答案几乎与问题完全无关。它可能看起来不相关,因为它似乎只是一个重构,但它肯定是相关的。OP是重新实例化的每次调用该方法时触发随机生成器,因此
nextDouble
将始终返回随机序列中的第一个双精度。此答案仅实例化随机生成器一次,每次调用
getNext
时,它实际上会逐步遍历随机序列,每次返回不同的数字。毫秒秒nd是一个很长的时间,使用System.nanoTime()@kukis会安全得多。这没关系。它只是一个数字,在每个程序启动时都不一样。因为你的程序只设置一次种子。使用“new Random()”相当于或更好,请参阅source:public Random(){this(seedUniquifier()^System.nanoTime());}假设我在类中定义了new Random(42),在另一个类中,我再次只做new Random(),得到了不同的结果……有没有任何技术可以全局设置随机种子,并且对于每个类,即使初始化new Random(),我也会得到每个类的相同值。如果有人能回答,这将非常有帮助。@GauravKoradiya这通常是一个问题,并且明显违反了设计原则。因此,不,没有办法。您可以将种子或随机实例传递到需要的地方。在特殊情况下,当代码运行太快时,可以从同一种子开始