以 x,y 坐标为种子的随机数生成器

bak*_*kaa 6 random algorithm hash dimension

我正在寻找一种高效、均匀分布的 PRNG,它为平原中的任何整数点生成一个随机整数,坐标 x 和 y 作为函数的输入。

int rand(int x, int y)
Run Code Online (Sandbox Code Playgroud)

每次输入相同的坐标时,它必须提供相同的随机数。

您知道可以用于此类问题以及更高维度的算法吗?

我已经尝试使用像 LFSR 这样的普通 PRNG 并将 x,y 坐标合并在一起以将其用作种子值。像这样的东西。

int seed = x << 16 | (y & 0xFFFF)
Run Code Online (Sandbox Code Playgroud)

这种方法的明显问题是种子不会迭代多次,而是针对每个 x,y 点再次初始化。如果您将结果可视化,这会导致非常丑陋的非随机模式。

我已经知道使用某种大小(如 256)的混洗排列表的方法,您可以像这样从中得到一个随机整数。

int r = P[x + P[y & 255] & 255];
Run Code Online (Sandbox Code Playgroud)

但是我不想使用这种方法,因为范围非常有限,周期长度受限,内存消耗很高。

感谢您提供任何有用的建议!

bak*_*kaa 7

我找到了一个基于xxhash算法的非常简单、快速且足够的hash函数。

// cash stands for chaos hash :D
int cash(int x, int y){   
    int h = seed + x*374761393 + y*668265263; //all constants are prime
    h = (h^(h >> 13))*1274126177;
    return h^(h >> 16);
}
Run Code Online (Sandbox Code Playgroud)

它现在比我上面描述的查找表方法快得多,而且看起来同样随机。我不知道与 xxhash 相比随机属性是否好,但只要它看起来随机,这对我的目的来说是一个公平的解决方案。

这是像素坐标作为输入的样子:

在此处输入图片说明

  • @sascha 我添加了我的函数的绘图图像。看起来很随意。我的算法与 xxhash 的工作原理类似,只是为了提高性能而减少了一些曲折。xxhash 在内部也适用于溢出。https://github.com/Cyan4973/xxHash/blob/master/xxhash.c 例如从第 370 行到第 375 行。这不是算法的缺陷。我不能使用像 LCG 这样的生成器,因为它们被设计为在一个序列中一个接一个地计算一个随机数。在 GPU 中,我必须并行计算它们。 (3认同)