25

特定の確率で乱数を生成したいのですが、方法がわかりません。

1から3までの数字が必要です

num = ceil(rand*3);

しかし、たとえば生成する確率が異なるには、異なる値が必要です。

0.5 chance of 1
0.1 chance of 2
0.4 chance of 3

これは簡単だと思いますが、どうすればよいかわかりません。

4

7 に答える 7

46

簡単な解決策は、( を使用して) 一様分布の数値を生成し、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 つのセグメントに分割します。各セグメントの長さは、対応する確率に比例します。. あなたの場合、次のようになります。

  • 番号 1 に対応するセグメント [0, 0.5)。
  • セグメント [0.5, 0.6)、番号 2 に対応。
  • 番号 3 に対応するセグメント [0.6, 1]。

rいずれかのセグメントに収まる確率は、各数値に必要な確率に比例します。sum(r >= cumsum([0, prob]))は、整数をセグメントの 1 つにマッピングするための優れた方法です。

拡大

乱数のベクトル/行列の作成に興味がある場合は、ループまたは を使用できますarrayfun

r = rand(3); % # Any size you want
x = arrayfun(@(z)sum(z >= cumsum([0, prob])), r);

もちろん、ベクトル化されたソリューションもあります。私はそれを書くのが面倒です。

于 2012-12-17T12:24:49.210 に答える
9

これまでの答えは正しいですが、大きな入力の場合は遅くなります: 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]));
于 2013-12-04T12:37:11.377 に答える
5
>> 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必要に応じて配布されます。

于 2012-12-17T18:54:21.140 に答える
5

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);

これが最も簡単な方法だと思います。

于 2016-10-30T14:50:48.483 に答える
4

もう少し一般的な解決策は次のとおりです。

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)
于 2012-12-17T16:24:13.623 に答える