有效地生成不同的随机数

Generating distinct random numbers efficiently

我的主要目的是随机有效地在图像的像素上分布缓冲区,但我一直坚持生成 distinct 随机数。我只是想要生成介于 0N 之间的数字,但我也希望这些数字是不同的。另请注意,N 通常会很大,例如 2000 万,并且算法不必是加密安全的。

我不能使用随机洗牌方法,因为 N 很大。我做了一些搜索,发现 Linear congruential generator 但参数 m 必须是质数,但我的 N 有时不是。

最后,我尝试了以下方法,但它不是很有效和可靠,因为它可能会抛出 超出最大调用堆栈大小 错误。

next(max: number)
{
    let num = LCG.next()
    if (num <= max) return num
    return next(max)
}

如果数字不同,则它们不是随机的。随机数可以重复;从不断减少的集合中选择不同的数字。就是选号有替换和没有替换的区别。

您需要 0 到 2000 万之间的数字。正如您所发现的,这对于洗牌来说太大了。最好使用加密。因为加密是一对一的,所以只要您有不同的输入,您就会得到不同的输出。只需加密 0, 1, 2, 3, ... 你就会得到不同的输出。

您谈到使用线性同余 PRNG,所以我认为安全性不是很重要。 2000 万大约是 2^24 或 2^26,因此您可以编写一个简单的四轮 Feistel cipher sized appropriately to do the work. Alternatively, use a standard library cipher with one of the Format preserving 方法来将输出保持在您想要的范围内。