有效地生成不同的随机数
Generating distinct random numbers efficiently
我的主要目的是随机有效地在图像的像素上分布缓冲区,但我一直坚持生成 distinct 随机数。我只是想要生成介于 0 和 N 之间的数字,但我也希望这些数字是不同的。另请注意,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 方法来将输出保持在您想要的范围内。
我的主要目的是随机有效地在图像的像素上分布缓冲区,但我一直坚持生成 distinct 随机数。我只是想要生成介于 0 和 N 之间的数字,但我也希望这些数字是不同的。另请注意,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 方法来将输出保持在您想要的范围内。