是否有算法或函数可以输出给定 n 个数值的随机数?

问题描述

所以我一直在开发一款利用程序地形和结构生成的游戏。现在,我正在处理结构生成——我使用了 Poisson-disc 采样,我计划在我的世界中实现块。但是,我的采样依赖于一颗种子。有没有办法接受 3 个或更多数字以输出与这些数字有某种关系的随机数?

另一方面,随机数不必在输入的可能范围内。

如果不可能,是否还有其他范式可以在无限程序生成的世界上实施泊松盘采样(或其替代方案)以创建结构?我有点卡住了。

示例:

Random x = new Random(138013,28282,37920)
x.nextInt() = 38309
Random y = new Random(138012,37920)
y.nextInt() = 28323
Random z = new Random(138013,37920)
z.nextInt() = 38309
//new Random(a,b,c).nextInt() does not have to be within ranges [a,b],[a,c],[b,c]

解决方法

您可以通过连接这三个值来创建种子:

new Random(138013,28282,37920) => new Random("138013" + "28282" + "37920")

这不是有效的代码,但我希望你明白原理。然后应该将字符串转换为long。如果数字太大太久,也许您可​​以应用ceratain modulo。喜欢 138013 % 10000 并对每个值都这样做。或者您可以将这三个值相加。

,

使用某些值的加密散列通常会导致结果的确定性降低。在您的情况下,例如:

    public Random fromCoords(long x,long y,long z) throws Exception {
        var buf = ByteBuffer.allocate(4 * 8);

        buf.putLong(world_seed);
        buf.putLong(x);
        buf.putLong(y);
        buf.putLong(z);

        buf.flip();

        var md = MessageDigest.getInstance("SHA-256");
        md.update(buf);

        var seed = ByteBuffer.wrap(md.digest()).getLong();

        return new Random(seed);
    }

可能足够了,但不是特别有效。如果这是一个问题,您可以使用一些小技巧代替 ByteBuffer 来避免大多数不必要的堆分配。