我已经考虑了一段时间但无济于事......
如何创建一个带有轻微的伪随机数生成器(我们只在数百万甚至数十亿次迭代/测试之后才会说明)偏向于单个数字。因此,例如,如果我们的生成器正在生成0,1,2,...,98,99的数字,我们希望略微偏向47.
我觉得应该有一个聪明的数论解决方案,但我找不到任何东西。很想知道y'所有人的想法!
答案 0 :(得分:2)
您可以使用均匀分布的任何好的随机发生器。
如果您的子范围的长度为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
和相应的公式修正(此方法可提供任何所需的合理偏差值)。
答案 1 :(得分:0)
我认为挑出一些数字的最简单方法是明确地做。因此,您可能有两个非常好的随机生成器,并使用其中一个来控制是从第二个返回输出还是硬编码值:
if(controlGeneator.generate01Float() < Eps) {
return 42;
}
else {
return mainGenerator.generateNextInRange()
}
关于这一点的好处是它即使目标范围实际上是整个32位范围或其他任何东西也能工作。另外,通过更改Eps
,您可以控制偏见。
明显的缺点是,为了使这个工作真的很好,controlGeneator
和mainGenerator
更好地完全独立,这是一项艰巨的工作。一个想法可能是使用不同的种子(如seed
和seed + 1
)来初始化它们,然后使用不同的循环,例如在每个调用中实际绘制来自controlGeneator
的2个随机数和3个来自mainGenerator
代替比例1:1
。
P.S。 IANAL但在机会游戏中作弊可能是非法的。
答案 2 :(得分:-2)
线性同余Genetaor是生成伪随机数的最常见和最古老的算法,你应该具有重复关系的知识
Xn+1 = (aXn + c) mod c
where X is the sequence of pseudo-random values
m, 0< m- modulus
a, 0< a <m- multiplier
c, 0< = c<m- increment
x0, 0<=x0<m- the seed or start value
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
srand(time(NULL));
int i;
for(i = 0; i<5; i++)
printf("%d\t", rand()%10);
}