如何从给定概率的数组中获取数字

时间:2015-02-11 17:55:33

标签: matlab

我有两个数字1,2,概率分别为.7和3。如何根据给定的概率选取一个数字。

2 个答案:

答案 0 :(得分:4)

直接实施

你需要的是一个缩放的伯努利随机数发生器。原始的伯努利随机变量是0或1,你需要1或2.所以下面的代码应该有效:

a = binornd(1,0.3)+1;

第一个参数是维度(这里是1,参见MATLAB文档),第二个参数是获得1的概率。通过加1,这就成为获得2的概率。

警告:对于没有幽默感的人,建议不要使用其他答案。

令人讨厌的实施

您可以使用统一随机生成器进行调整:

a = rand; %in (0,1) range
result = 1*(a<=0.7) + 2*(a>0.7);

更清洁的方式(感谢Luis Mendo):

result = 1 + (rand>.7);

Über-Geeky实施

假设tic...toc中的小数部分的某些数字是均匀随机的:

tic
A = rand(12060, 4400);
B = rand(12000, 4430);
t=toc;
t=round(t*10^3);
t = mod(t, 10);
randVal = (t<=6)*1 + (t>6)*2;

扩展Über-Geeky实施

扩展前一种方法,但这次使用伪随机生成的32位数(每个位如前一种方法中那样生成),将其除以最大值,从而获得0到0之间的近似均匀分布的变量1。

randNum = 0;
for i=0:31
   tic
   A = rand(12000, 4400);
   B = rand(12000, 4400);
   t=toc;
   t=round(t*10^3);
   randNum = randNum + mod(t,2)*2^i;
end
%randNum is a uniformly distributed number between 0 and 2^32 - 1

randNum = randNum/(2^32);

final = (randNum<=0.7)*1 + (randNum>0.7)*2;

答案 1 :(得分:0)

选择具有特定分布的数字的基本问题非常普遍。您的示例是一种非常简单的形式,尽管您的问题标题意味着您对通用解决方案感兴趣。

这是一个简单的函数,它通过选择0到1的随机数来工作。然后循环遍历分布数组中的值,从分布的cdf累积它们。一旦累加器中的值超过随机值,就返回索引。

function idx = randWithDist(dist)
    r = rand;
    a = 0;
    idx = 0;
    while(r > a)
        idx = idx + 1;
        a = a + dist(idx);
    end
end

你的2值示例有点过分,但你会像这样使用它:randWithDist([.7 .3])

如果您使用它来从任意数组中选择值(就像您的主题所暗示的那样),只需使用返回的值作为数组的索引:

dist = [.2 .3 .4 .1];
val = [1 2 10 11];

samples = [];
for i=1:10000
    samples = [samples val(randWithDist(dist))];
end

histogram(samples);

这应该选择1.2概率,2选择.3,10选择.4和11选择.1。直方图显示它似乎正常工作。

histogram plot from above code

我要做的另一个调整是为了让它能够处理更多通用输入,将第一行改为r = rand * sum(dist)。这会自动规范化分布,因此它不必总和为1。