如何在-32000和32000之间生成随机均匀分布的数字

时间:2013-05-29 13:15:28

标签: c

如何在-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;
}

此代码产生非均匀分布。我认为对于均匀分布,我需要去除模数运算。请提出任何建议。

3 个答案:

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