我正在学习编程课程,我们正在使用C ++。 我们有一个赋值,在某些时候,我们需要编写一个函数,它会在[upper,lower]区间返回一个随机数。我使用了以下内容:
lower + (int) (upper * (rand() / (RAND_MAX + 1.0)));
我没有忘记使用srand
更改srand((unsigned int) time(0))
。
然而,我每次都获得相同的价值!我向我的教授寻求帮助,经过一番调查,他发现rand()
生成的第一个数字不是随机的......高阶位保持不变,因为这个实现使用了它们,所以结果并不是我的预期。
是否有一个更优雅,更简单的解决方案,而不是丢弃第一个值或使用余数来达到我想要的效果?
非常感谢您的关注!
〜旧金山
编辑:谢谢大家的意见。我不知道rand()
是如此糟糕的RNG:P
答案 0 :(得分:2)
鉴于rand()不是一个非常强大的随机数生成器,标准方法增加的少量偏差可能不是问题:(更高 - 更低)当然需要小于MAX_RAND。
lower + rand() % (higher-lower+1);
由一个错误修复。
答案 1 :(得分:1)
rand()
不是一个好的随机数生成器。除了你观察到的问题,它的周期长度可能非常短。
考虑使用其中一个gsl
random number generators。
答案 2 :(得分:1)
根据您使用的操作系统,除random()
外,您还可以使用rand()
。这会产生比rand()
好得多的伪随机数。查看<stdlib.h>
和/或man 3 random
。
答案 3 :(得分:1)
您的代码很好,但您应该替换
lower + (int) upper * (rand() / (RAND_MAX + 1.0));
与
lower + (int) (upper - lower + 1)*(rand() / (RAND_MAX + 1.0));
以下代码在我的机器上运行良好:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define lower 10
#define upper 20
int main(void)
{
int i;
int number;
srand(time(0));
for(i=0; i<10; i++)
{
number = lower + (int) (upper - lower + 1)*(rand() / (RAND_MAX + 1.0));
printf ("%d\n", number);
}
return 0;
}
当然,由于time(0)
以秒为单位给出当前时间 ,因此同一秒内的两次执行会产生相同的结果。
答案 4 :(得分:1)
C ++ 0x随机数库(也可用于TR1和Boost)最终解决了一些令人讨厌的rand问题。它允许获得可用于正确播种的真实随机性(random_device),然后您可以使用快速且良好的伪随机生成器(mt19937),并且可以对其应用合适的分布(例如,uniform_int用于最小 - 最大范围,等于每个值的概率。)
它也不像rand()那样使用全局隐藏状态,因此在多线程程序中不会出现任何问题。
由于所有的模块化,它使用起来比简单地调用rand要困难一些,但是它的好处远远超过了更陡峭的学习曲线。