我使用NextDouble()
生成统一的随机数。我用500个不同的种子生成随机数,发现生成的均匀随机数偏向更高的统一数(平均值为0.93)。这是非常荒谬的。然后我将种子除以10000,产生的随机数是完美的(平均值为0.51)。
我发现种子不应该超过48位,因此确保我提供的种子(NextDouble()
的种子是随机生成的nextLong(),种子= 12345)少于48位。然后我重新生成了500次随机数,发现了同样的问题。是否有人与NextDouble()
有类似的问题?
请参阅以下代码:
Random randObject = new Random();
randObject.setSeed(12345);
long[] seed = new long[501];
for (int i = 1; i<=500; i++)
seed[i] = (long)( ( randObject.nextLong() / (double)Long.MAX_VALUE ) * Math.pow( 2, 48 ) ); // to make sure seed is not more than 48 bits
for (int i = 1; i<=500; i++)
{
randObject.setSeed(seed[i]);
randObject.nextDouble();
}
由于
答案 0 :(得分:0)
恭喜
我发现种子不应超过48位,因此确保我提供的种子(NextDouble()的种子是使用seed = 12345的nextLong()随机生成的,少于48位。
您通过实验证明java.util.Random
是48位LCG生成器
从其来源
48: * The algorithm is described in <em>The Art of Computer Programming,
49: * Volume 2</em> by Donald Knuth in Section 3.2.1. It is a 48-bit seed,
50: * linear congruential formula.
51: *
链接http://developer.classpath.org/doc/java/util/Random-source.html
答案 1 :(得分:0)
Java Random
是linear congruential generator (LCG),它从当前状态传播下一个状态。您正在使用LCG的输出来自行播种,因此您的每个种子都将与其他种子产生的输出相关联。从那时起,关于结果的分布行为,所有的赌注都是关闭的。
从/dev/random
为您的500个流播种,或者使用完全不同类别的生成器(例如feedback shift register或Mersenne twister)的输出。然后,如果您仍然在观察偏见,请写一份期刊论文。
答案 2 :(得分:0)
Java-8版本似乎提供了不同的图片:
public void test() {
Random r1 = new Random();
Random r2 = new Random();
r1.setSeed(12345);
double average = IntStream.range(0, 5000)
// 5000 random longs.
.mapToLong(i -> r1.nextLong())
// Used as seeds to a Random
.mapToDouble(l -> {
r2.setSeed(l);
return r2.nextDouble();
})
// Gather stats.
.summaryStatistics()
// Average,
.getAverage();
System.out.println("Average: " + average);
}
相当一致地打印0.5000...
。