使用给定概率matlab生成随机数

Eam*_*voy 25 random math matlab probability

我想生成一个给定概率的随机数,但我不知道如何:

我需要1到3之间的数字

num = ceil(rand*3);
Run Code Online (Sandbox Code Playgroud)

但我需要不同的值来产生不同的生成概率,例如.

0.5 chance of 1
0.1 chance of 2
0.4 chance of 3
Run Code Online (Sandbox Code Playgroud)

我确信这很简单,但我想不出怎么做.

Eit*_*n T 46

简单的解决方案是生成一个具有均匀分布(使用rand)的数字,并稍微操作它:

r = rand;
prob = [0.5, 0.1, 0.4];
x = sum(r >= cumsum([0, prob]));
Run Code Online (Sandbox Code Playgroud)

或者在单行中:

x = sum(rand >= cumsum([0, 0.5, 0.1, 0.4]));
Run Code Online (Sandbox Code Playgroud)

说明

r是一个介于0和1之间的均匀分布的随机数.为了生成1到3之间的整数,技巧是将[0,1]范围划分为3个段,其中每个段的长度与其对应的概率成比例.在你的情况下,你会有:

  • 段[0,0.5),对应于数字1.
  • 段[0.5,0.6),对应于数字2.
  • 段[0.6,1],对应于数字3.

概率r掉落内的任何段的正比于你想为每个号码的概率.sum(r >= cumsum([0, prob]))只是将整数映射到其中一个段的奇特方式.

延期

如果您对创建随机数的向量/矩阵感兴趣,可以使用循环或arrayfun:

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

当然,还有一个矢量化解决方案,我只是懒得写它.

  • 矢量化解:`sum(bsxfun(@ ge,r,cumsum([0,prob]),2)`其中`r`是列向量,`prob`是行向量. (3认同)

Ale*_*son 9

到目前为止,答案是正确的,但对于大输入来说速度很慢:O(m*n)其中n是值的数量,m是随机样本的数量.这是一个O(m*log(n))版本,它利用了cumsum结果的单调性和二进制搜索histc:

% assume n = numel(prob) is large and sum(prob) == 1
r = rand(m,1);
[~,x] = histc(r,cumsum([0,prob]));
Run Code Online (Sandbox Code Playgroud)


Ser*_*erg 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
Run Code Online (Sandbox Code Playgroud)

x 根据需要分发.


mam*_*maj 5

使用统计和机器学习工具箱中的randsample函数,可以生成具有指定概率质量函数(pmf)的随机数:

pmf = [0.5, 0.1, 0.4];
population = 1:3;
sample_size = 1;

random_number = randsample(population,sample_size,true,pmf);
Run Code Online (Sandbox Code Playgroud)

我认为这是最简单的方法。