特定の確率で乱数を生成したいのですが、方法がわかりません。
1から3までの数字が必要です
num = ceil(rand*3);
しかし、たとえば生成する確率が異なるには、異なる値が必要です。
0.5 chance of 1
0.1 chance of 2
0.4 chance of 3
これは簡単だと思いますが、どうすればよいかわかりません。
特定の確率で乱数を生成したいのですが、方法がわかりません。
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
以下は、結果の単調性と で使用される二分探索を利用する O(m*log(n)) バージョンですhistc
。
% 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 Toolboxrandsample
の関数を使用して、指定された確率質量関数 (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)