具有轻微偏差的伪随机数生成器

Pseudorandom Number Generator with slight bias

这个问题我想了很久都没用...

如何创建一个带有 轻微 的伪随机数生成器(我们说的是在 iterations/tests 数百万甚至数十亿之后才明显)偏向一个数字。因此,例如,如果我们的生成器从 0,1,2,...,98,99 生成数字并且我们想要 47 的轻微偏差。

我觉得好像应该有一种聪明的数论解决方案,但我找不到任何东西。很想知道你们的想法!

您可以使用任何具有均匀分布的优秀随机生成器。

如果您的子范围长度为 N,则生成 0..K*N+1 范围内的值(不包括右边界)。如果结果R小于K*N,输出R mod N,否则输出首选值。

在这种情况下,我们有所有元素的概率 p=K/(K*N+1) 和首选元素的概率 q = p + delta = K/(K*N+1) + 1/(K*N+1) = (K+1)/(K*N+1)

如果您有 N 和一些偏差标准,请计算 K 以提供接近的偏差值。

如果您需要更高的精度,请使用随机范围 0..K*N+F 并进行相应的公式修正(此方法可提供任何所需的合理偏差值)。

我认为挑出一些数字的最简单方法是明确地做。所以你可能有两个非常好的随机生成器,并使用其中一个来控制你 return 输出第二个还是硬编码值:

if(controlGeneator.generate01Float() < Eps) {
     return 42;
}
else {
    return mainGenerator.generateNextInRange()
}

这样做的好处是,即使目标范围确实是整个 32 位范围或其他范围,它也能正常工作。此外,通过更改 Eps,您可以控制偏差。

明显的缺点是,要使其真正发挥作用,controlGeneatormainGenerator 最好完全独立,这是一项艰巨的工作。一个想法可能是使用不同的种子(如 seedseed + 1)来初始化它们,然后使用不同的循环,例如在每次调用中实际上从 controlGeneator 中抽取 2 个随机数,从中抽取 3 个随机数mainGenerator 而不是比例 1:1.

P.S。 IANAL 但在机会游戏中作弊可能是非法的。