使用种子的Java随机数



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

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

每次我给一个种子并尝试生成100个数字时,它们都是一样的
如何解决此问题?

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

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

伪随机数生成器

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

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

你的代码应该是这样的:

private Random generator = new Random();
double randomGenerator() {
return generator.nextDouble()*0.5;
}

简单的方法是使用:

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

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

您不应该在方法范围内创建新的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会增加任何价值。把它放在你的一个正在使用它的类中。

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

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

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

double randomGenerator() {
return ThreadLocalRandom.current().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;
}

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

最新更新