如何在-32000到32000的范围内生成随机均匀分布的数字。我已经完成了如何在没有均匀分布的情况下生成随机数。非均匀分布的代码如下:
sint16 min= Some value a;
sint16 max= Some value b;
sint32 array[1536];
uint16 i;
for(i=0; i<1536; i++) {
r= rand()%(max+min+1)+min;
array[i]=r;
}
此代码产生非均匀分布。我认为对于均匀分布,我需要去除模数运算。请提出任何建议。
答案 0 :(得分:4)
当跨度(最大+ 1分钟)与RAND_MAX相比较小时,非均匀性很小,并且人们经常在可以容忍它的应用中使其不均匀。 (但是,它们通常会在整个区间内分布不均匀性。您的代码将多余元素分组到区间的低端。)
如果您希望分布完全一致,则必须拒绝某些样本。这会减少可能值的数量,使其成为所需跨度的完美倍数:
Let span = max+1-min.
Let M = the largest multiple of span not greater than RAND_MAX+1.
// Get samples from random-number generator until one is in range.
do
sample = rand();
while (M <= sample);
// Scale and translate to desired interval.
sample = sample / (M/span) + min;
(这假设跨度≤RAND_MAX+ 1。如果你想要一个比rand
提供的更大的跨度,你必须“粘贴”来自rand
的样本以产生更大的数字。但是,它仍然会必须使用拒绝来修剪样本,除非跨度是RAND_MAX + 1的某个幂的因子。)
答案 1 :(得分:0)
假设rand()
返回[0,RAND_MAX]
范围内的均匀分布的整数,只要[0,N]
,就可以轻松生成N<=RAND_MAX
范围内均匀分布的数字。< / p>
int uniform_rand(int N)
{
int res;
do{
res=rand();
}while(res>N);
return res;
}
当然,只要[min,max]
和max-min <= RAND_MAX
,您也可以将分布转移到范围max>=min
。
int sample = min + uniform_rand(max-min);
工作示例
http://coliru.stacked-crooked.com/a/50fa635270697fbf
注意
虽然此解决方案很简单,但您可以使用以下方法显着提高uniform_rand()
功能的性能:
正如埃里克的回答所指出的那样。N的最大倍数不大于RAND_MAX + 1.
编辑:在咖啡馆的合法批评之后完全修改了我的初步答案。 (见评论)
答案 2 :(得分:-3)
模运算只能略微降低数值,所以我们可以非严格地考虑分布均匀。 在这方面,您可以生成-32000,32000之间的随机数,如下所示:
r = rand() % 64000;
r -= 32000;