创建一个小于最大给定值的随机数

我想做的是创建一个函数,该函数接受一个参数,该参数是随机生成应该创建的数字的限制。 我经历过一些生成器只重复生成一遍又一遍的数字。

如何使生成器不能连续返回相同的数字。 有人可以帮助我实现我的目标吗?

int randomGen(int max) { int n; return n; } 

rand获得均匀分布结果的最简单方法是这样的:

 int limited_rand(int limit) { int r, d = RAND_MAX / limit; limit *= d; do { r = rand(); } while (r >= limit); return r / d; } 

结果将在0limit-1的范围内,并且每个都将以相等的概率发生,只要0RAND_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 ),但是你遇到了一个不同的问题。

这个怎么样:

  int randomGen(int limit) { return rand() % limit; } /* ... */ int main() { srand(time(NULL)); printf("%d", randomGen(2041)); return 0; } 

任何伪随机生成器都会在一段时间内反复重复这些值。 C只有rand() ,如果你使用它,你应该使用srand()明确初始化随机种子。 但可能你的平台比这更好。

在POSIX系统上,您可以在man drand48页面下找到一整套函数。 他们有一个明确的时期和质量。 你可能在那里找到了你需要的东西。

如果没有对平台的随机生成器的明确了解, 请不要执行rand() % max 。 简单随机数生成器的低位字节通常根本不是随机的。

改为使用(返回介于最小值和最大值之间的数字):

 int randomIntegerInRange(int min, int max) { double tmp = (double)rand() / (RAND_MAX - 1.); return min + (int)floor(tmp * (max - min)); } 

更新 :上述解决方案存在偏差(请参阅注释以获得解释),并且可能无法产生统一的结果。 我不删除它,因为它是不做的不自然的例子。 请使用本主题其他地方推荐的拒绝方法。