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

时间:2010-09-19 17:58:24

标签: c random

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

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

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

4 个答案:

答案 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;
}

结果将在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),但是你遇到了一个不同的问题。

答案 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页面下找到一整套功能。他们有一个明确的时期和质量。你可能在那里找到了你需要的东西。