我喜欢做的是创建一个函数,该函数接受一个参数,该参数是随机生成应该创建的数字的限制。我经历过一些生成器只重复生成一遍又一遍的数字。
如何创建一个不会连续返回相同数字的生成器。有人可以帮助我实现我的目标吗?
int randomGen(int max)
{
int n;
return n;
}
答案 0 :(得分:7)
从rand
获得均匀分布的结果的最简单方法是这样的:
int limited_rand(int limit)
{
int r, d = RAND_MAX / limit;
limit *= d;
do { r = rand(); } while (r >= limit);
return r / d;
}
结果将在0
到limit-1
的范围内,只要值0
到RAND_MAX
都具有相同的概率,每个都会以相同的概率发生原始的rand
函数。
其他方法,例如模块化算术或没有使用循环的分割引入偏差。通过浮点中间体的方法不能避免这个问题。从rand
获得良好的随机浮点数至少同样困难。如果你想要随机浮点数,使用我的函数进行整数(或改进它)是一个很好的起点。
编辑:这是对偏见的含义的解释。假设RAND_MAX
为7且limit
为5.假设(如果这是一个好的rand
函数)输出0,1,2,...,7都是同等可能的。取rand()%5
会将0,1,2,3和4映射到自身,但将5,6和7映射到0,1和2.这意味着值0,1和2是两倍可能会弹出值3和4.如果你尝试重新缩放和分割,会发生类似的现象,例如使用rand()*(double)limit/(RAND_MAX+1)
这里,0和1映射到0,2和3映射到1,4映射到2,5和6映射到3,而7映射到4。
RAND_MAX
的幅度可以稍微减轻这些影响,但如果limit
很大,它们可以回来。顺便说一句,正如其他人所说的那样,线性同余PRNG(rand
的典型实现),低位倾向于表现得非常糟糕,因此当limit
是2的幂时使用模运算可能避免我描述的偏见问题(因为limit
通常在这种情况下均匀地划分RAND_MAX+1
),但是你遇到了一个不同的问题。
答案 1 :(得分:2)
这个怎么样:
int randomGen(int limit)
{
return rand() % limit;
}
/* ... */
int main()
{
srand(time(NULL));
printf("%d", randomGen(2041));
return 0;
}
答案 2 :(得分:0)
如果没有明确了解您平台的随机生成器,不执行rand() % max
。简单随机数生成器的低位字节通常不是随机的。
改为使用(返回介于最小值和最大值之间的数字):
int randomIntegerInRange(int min, int max)
{
double tmp = (double)rand() / (RAND_MAX - 1.);
return min + (int)floor(tmp * (max - min));
}
更新:上述解决方案存在偏差(请参阅说明以获得解释),并且可能无法产生统一的结果。我不删除它,因为它是不该做的的一个非常自然的例子。请使用本主题其他地方推荐的拒绝方法。
答案 3 :(得分:0)
任何伪随机生成器都会在一段时间内反复重复这些值。 C只有rand()
,如果你使用它,你应该使用srand()
明确初始化随机种子。但是你的平台可能比那更好。
在POSIX系统上,您应该在man drand48
页面下找到一整套功能。他们有一个明确的时期和质量。你可能在那里找到了你需要的东西。