【问题标题】:Generating random numbers with a vector of integers as seed in Java在Java中使用整数向量作为种子生成随机数
【发布时间】:2011-08-21 06:04:49
【问题描述】:

我想生成可重现的随机数,表示 3 维空间中不同点的数量,例如

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

我希望相同的输入始终产生相同的平局。我不想提前生成所有值,因为会太多。

我希望不同位置的抽签是独立的。我还希望使用不同种子的相同位置的抽签是独立的。这排除了取四个参数的总和或乘积,并将其用作种子。

【问题讨论】:

  • “我想要..”我想要一匹小马。现在我们已经完成了我们想要的分享,您有问题吗?

标签: java random numbers random-seed


【解决方案1】:

怎么样

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

(由于构造函数的种子参数实际上是 64 位,因此您可以通过例如在 xor:ing 之前将两个整数上移 32 位来获得更好的“传播”)


另一个简单的解决方案是做类似的事情

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

【讨论】:

    【解决方案2】:

    Random 类使用 48 位种子,可以方便地分成三块,每块 16 位,就像这样。

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

    【讨论】:

      【解决方案3】:

      Java 有 Random(long seed) 构造函数,但它只需要一个 long 值。

      但您不必太担心,因为您可以将(数学)函数应用于向量和种子以生成单个数字。穷人的版本只是简单地添加数字:

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

      但您可能已经注意到,这并不是最好的,因为它对 (1,0,0) 和 (0,1,0) 和 (0,0,1) 产生相同的结果。我相信你可以想出一个更好的函数,比如seed + 31*31*x + 31*y + z 或类似的。

      【讨论】:

        【解决方案4】:

        setSeed() API 中所述,java.util.Random 使用 48 位种子。您的模型可能会建议定义一个合适的函数来散列您的三个整数。或者,您可以使用自定义实现扩展 java.util.Random

        【讨论】:

          猜你喜欢
          • 2020-12-15
          • 1970-01-01
          • 2017-08-29
          • 2021-05-15
          • 2011-03-19
          • 1970-01-01
          • 2023-03-21
          • 2011-04-07
          • 1970-01-01
          相关资源
          最近更新 更多