我想做的是创建一个函数,该函数需要一个参数,该参数是随机生成应创建的数量的限制。我曾经历过一些重复生成的数字的生成器。创建一个小于最大给定值的随机数
我怎样才能让一个发电机不会连续返回相同的数字。有人可以帮助我实现我的目标吗?
int randomGen(int max)
{
int n;
return n;
}
我想做的是创建一个函数,该函数需要一个参数,该参数是随机生成应创建的数量的限制。我曾经历过一些重复生成的数字的生成器。创建一个小于最大给定值的随机数
我怎样才能让一个发电机不会连续返回相同的数字。有人可以帮助我实现我的目标吗?
int randomGen(int max)
{
int n;
return n;
}
如何:
int randomGen(int limit)
{
return rand() % limit;
}
/* ... */
int main()
{
srand(time(NULL));
printf("%d", randomGen(2041));
return 0;
}
这种常见的方法是不正确的,并导致有偏倚的随机数,除非'limit'是2的幂。 – 2010-09-19 18:14:08
简单,并且OP没有提及每个数字需要ab等概率。 – 2010-09-19 18:18:41
如果rand是一个线性同余发生器,它将给出有偏差的结果,即使限制是二的幂。 – 2010-09-19 18:26:58
没有你的平台的随机生成的显性知识,不做rand() % max
。简单随机数发生器的低位字节通常不是随机的。
使用代替(返回一个数分钟包容性和最大非包含之间):
int randomIntegerInRange(int min, int max)
{
double tmp = (double)rand()/(RAND_MAX - 1.);
return min + (int)floor(tmp * (max - min));
}
更新:上面的溶液被偏置(见说明意见),并且将可能不会产生效果均匀。我不删除它,因为它是一个非自然的例子不能做什么。请使用此线程中推荐的拒绝方法。
不要那样做。 – 2010-09-19 18:17:41
@Matt:这个很有效。用rand()的其他知识,我会用2的幂和拒绝来做模数。但在这里,如果rand()是一个线性同余废话,没有更好的办法。 – 2010-09-19 18:25:12
该解决方案不能解决偏见。 – 2010-09-19 18:36:48
任何伪随机生成器都会在一段时间内一遍又一遍地重复这些值。 C只有rand()
,如果你使用它,你应该用srand()
明确初始化随机种子。但是可能你的平台比这更好。
在POSIX系统上有一整套功能,您应该在man drand48
页面下找到。他们有一个明确的时期和质量。你可能会找到你需要的,在那里。
从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
),但是您碰到不同的问题。
当然,如果限制> RAND_MAX,这将导致除数为0.(但也许这是一个好的事情,以避免你没有真正从你想要的范围获得统一的随机数。) – jamesdlin 2012-04-29 00:45:56
是的。如果你担心可能会发生,你应该使用一个函数来调用'rand'多次调用'rand'并追加这些位,直到在一个已知的固定幂级的大范围内有均匀分布。 – 2012-04-29 01:27:46
http://www.phanderson.com/C/random.html – miku 2010-09-19 17:59:15
http://www.geekpedia.com/tutorial39_Random-Number-Generation.html – miku 2010-09-19 18:00:55
http://en.wikipedia.org/wiki/List_of_random_number_generators – pmg 2010-09-19 18:16:37