可能性のある複製:
Objective-Cでの乱数の生成
範囲内の乱数を生成するにはどうすればよいですか?
これを実際に正しく理解するのは、ほとんどの人が理解するよりも少し難しいです。
int Rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
*/
int divisor = Rand_MAX/(limit+1);
int retval;
do {
retval = Rand() / divisor;
} while (retval > limit);
return retval;
}
%
(または/
)のみを使用して範囲内の数値を取得しようとすると、必然的にスキューが発生します(つまり、一部の数値は他の数値よりも頻繁に生成されます)。
%
を使用すると結果が歪む理由について:必要な範囲がRand_MAXの約数でない限り、スキューは避けられません。小さな数字から始める場合、その理由は簡単にわかります。キャンディーを10個(切り取ったり、壊したりすることはできないと想定)、3人の子供に均等に分配することを検討してください。明らかにそれはできません。すべてのキャンディーを配った場合、最も近いのは2人の子供が3つのキャンディーを手に入れ、そのうちの1人が4つを手に入れることです。
すべての子供が同じ数のキャンディーを手に入れる方法は1つしかありません。最後のキャンディーをまったく配らないようにしてください。
これを上記のコードに関連付けるために、キャンディーを1から10、子供を1から3に番号付けしてみましょう。最初の除算では、子供が3人いるため、除数は3です。次に、バケツからランダムなキャンディーを取り出し、その数を調べて3で割り、その子供に渡します。ただし、結果が3より大きい場合(つまり、キャンディーの数10を選択した場合)は、それを手渡す-私たちはそれを捨て、別のキャンディーを選びます。
もちろん、C++の最新の実装(つまり、C++ 11以降をサポートする実装)を使用している場合は、通常、標準ライブラリのdistribution
クラスを使用する必要があります。上記のコードはstd::uniform_int_distribution
と最も密接に対応していますが、標準ライブラリにはuniform_real_distribution
だけでなく、いくつかの不均一分布のクラスも含まれています(ベルヌーイ、ポアソン、通常、おそらく私が使用しない他のカップル) t現時点では覚えています)。
int Rand_range(int min_n, int max_n)
{
return Rand() % (max_n - min_n + 1) + min_n;
}
分数の場合:
double Rand_range(double min_n, double max_n)
{
return (double)Rand()/Rand_MAX * (max_n - min_n) + min_n;
}
[min、max)の範囲の整数値の場合:
double scale = (double) (max - min) / Rand_MAX;
int val = min + floor(Rand() * scale)