使用种子的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这通常是一个问题,并且明显违反了设计原则。因此,不,没有办法。您可以将种子或随机实例传递到需要的地方。在特殊情况下,当代码运行太快时,可以从同一种子开始