2

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

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

4

3 回答 3

4

当跨度 (max+1-min) 与 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;

(这假设 span ≤ RAND_MAX+1。如果您想要一个比rand提供更大的跨度,您必须将样本“粘贴在一起”rand以产生更大的数字。但是,仍然需要使用拒绝来修剪样本,除非跨度是 RAND_MAX+1 的某个幂的因数。)

于 2013-05-29T13:25:31.390 回答
0

假设rand(), 返回范围内均匀分布的整数[0,RAND_MAX],则可以很容易地生成范围内的均匀分布数[0,N],只要N<=RAND_MAX.

int uniform_rand(int N)
{
    int res;

    do{
        res=rand();
    }while(res>N);

    return res;
}

当然,您也可以改变分布以覆盖[min,max]范围。max-min <= RAND_MAXmax>=min

int sample = min + uniform_rand(max-min);

工作示例

http://coliru.stacked-crooked.com/a/50fa635270697fbf

注意

虽然此解决方案很简单,但您可以通过使用以下方法显着提高uniform_rand()函数的性能:

N 的最大倍数不大于 RAND_MAX+1。

正如埃里克的回答中指出的那样。


编辑:在 caf 的合法批评后完全修改了我的初步答案。(看评论)

于 2013-05-29T13:22:59.150 回答
-3

模运算对较小的数字只有一点点优势,因此我们可以不严格地考虑分布均匀。在这方面,您可以像这样生成 -32000,32000 之间的随机数:

r = rand() % 64000;
r -= 32000;
于 2013-05-29T13:28:09.657 回答