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;

(これは、スパン ≤ 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()このソリューションは簡単ですが、次を使用して関数のパフォーマンスを大幅に向上させることができます。

RAND_MAX+1 以下の N の最大倍数。

エリックの答えで指摘されているように。


編集:カフェの正当な批判の後、最初の回答を完全に修正しました。(コメントを参照)

于 2013-05-29T13:22:59.150 に答える
-3

モジュロ演算は、より低い数値にわずかな利点しか与えないため、分布が一様であると非厳密に考えることができます。これに関して、次のように -32000,32000 の間の乱数を生成できます。

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