简体   繁体   English

在Java中使用整数作为种子生成随机数

[英]Generating random numbers with a vector of integers as seed in Java

I want to generate reproducible random numbers representing quantities at different points in 3 dimensional space, eg 我想生成可再现的随机数,表示3维空间中不同点的数量,例如

double draw = rand(int seed, int x, int y, int z)

I want the same inputs to always produce the same draw. 我希望相同的输入始终产生相同的绘制。 I don't want to generate all the values in advance as there would be too many. 我不想提前生成所有值,因为会有太多值。

I want the draws for different positions to be independent. 我希望不同职位的抽签相互独立。 I also want draws for the same position with different seeds to be independent. 我还希望具有不同种子的相同位置的绘制独立。 This rules out taking the sum or product of the four arguments, and using this as a seed. 这排除了取四个参数的总和或乘积,并将其用作种子。

The Random class uses a 48-bit seed that's conveniently divided into three pieces of 16 bits in each, like so. 随机类使用一个48位种子,可以方便地将其分成3个16位的种子,就像这样。

private static long createSeed(long x, long y, long z) {
    return (z & 0xffff) << 32 + (yy & 0xffff) << 16 + (x & 0xffff);
} 

How about 怎么样

return new Random(seed ^ x ^ y ^ z).nextDouble();

(since the seed-argument to the constructor is actually 64 bits, you could get a better "spread" by, say shifting up two of your ints by 32 bits before xor:ing) (由于构造函数的种子参数实际上是64位,因此您可以通过将x中的两个int上移32位来获得更好的“传播”)


Another simple solution would be to do something like 另一个简单的解决方案是做类似的事情

Random rnd = new Random(seed);
rnd.setSeed(rnd.nextLong() ^ x);
rnd.setSeed(rnd.nextLong() ^ y);
rnd.setSeed(rnd.nextLong() ^ z);
return rnd.nextDouble();

Java has Random(long seed) constructor but it takes only a single long value. Java具有Random(long seed)构造函数,但它仅需要一个long值。

But you shouldn't worry much since you can apply a (mathematical) function to your vector and your seed to produce a single number. 但是,您不必担心,因为您可以对向量和种子应用(数学)函数以产生单个数字。 A poor man's version would be simply adding the numbers: 一个穷人的版本将简单地加上数字:

 Random rand = new Random(seed+x+y+z);

But as you probably noticed yourself, that isn't the best one as it yields the same result for (1,0,0) and (0,1,0) and (0,0,1). 但是,正如您可能已经注意到的那样,这并不是最好的方法,因为它对于(1,0,0)和(0,1,0)和(0,0,1)产生相同的结果。 I am sure you can think up a better function instead like seed + 31*31*x + 31*y + z or similar. 我敢肯定,您可以想出更好的功能,例如seed + 31*31*x + 31*y + z或类似的功能。

As noted in the setSeed() API, java.util.Random uses a 48-bit seed. setSeed() API中所述, java.util.Random使用48位种子。 Your model may suggest the definition of a suitable function to hash your three integer's. 您的模型可能会建议定义合适的函数以对三个整数进行哈希处理。 Alternatively, you can extend java.util.Random with a custom implementation. 另外,您可以使用自定义实现扩展java.util.Random

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM