与えられた確率で乱数を生成したいのですが、どうすればいいのかわかりません:
1〜3の数字が必要です
num = ceil(Rand*3);
しかし、生成する確率が異なるためには、異なる値が必要です。
0.5 chance of 1
0.1 chance of 2
0.4 chance of 3
これは簡単だと確信していますが、どうすればいいのか考えられません。
簡単な解決策は、( Rand
を使用して)均一な分布で数値を生成し、それを少し操作することです。
_r = Rand;
prob = [0.5, 0.1, 0.4];
x = sum(r >= cumsum([0, prob]));
_
またはワンライナーで:
_x = sum(Rand >= cumsum([0, 0.5, 0.1, 0.4]));
_
ここで、r
は0〜1の一様分布乱数です。1〜3の整数を生成するには、[0、1]の範囲を3つのセグメントに分割します。各セグメントの長さは対応する確率に比例します。あなたの場合、あなたが持っているでしょう:
r
がセグメントのいずれかに収まる確率は、各数値に必要な確率に比例します。 sum(r >= cumsum([0, prob]))
は、整数をセグメントの1つにマッピングするだけの派手な方法です。
乱数のベクトル/行列の作成に関心がある場合は、ループまたは arrayfun
を使用できます。
_r = Rand(3); % # Any size you want
x = arrayfun(@(z)sum(z >= cumsum([0, prob])), r);
_
もちろん、ベクトル化されたソリューションもあります。私はそれを書くのが面倒です。
これまでの答えは正しいですが、入力が大きい場合は遅くなります。O(m * n)ここで、nは値の数で、mはランダムサンプルの数です。 cumsum
の結果の単調性とhistc
で使用されるバイナリ検索を利用するO(m * log(n))バージョンを次に示します。
% assume n = numel(prob) is large and sum(prob) == 1
r = Rand(m,1);
[~,x] = histc(r,cumsum([0,prob]));
>> c = cumsum([0.5, 0.1, 0.4]);
>> r = Rand(1e5, 1);
>> x = arrayfun(@(x) find(x <= c, 1, 'first'), r);
>> h = hist(x, 1:3)
h =
49953 10047 40000
x
は必要に応じて配布されます。
Statistics and Machine Learning Toolboxのrandsample
関数を使用すると、指定された確率質量関数(pmf)で乱数を生成できます。
pmf = [0.5, 0.1, 0.4];
population = 1:3;
sample_size = 1;
random_number = randsample(population,sample_size,true,pmf);
これが最も簡単な方法だと思います。
もう少し一般的な解決策は次のとおりです。
r=Rand;
prob=[.5,.1,.4];
prob=cumsum(prob);
value=[1,2,3]; %values corresponding to the probabilities
ind=find(r<=prob,1,'first');
x=value(ind)