我有两个数字1,2,概率分别为.7和3。如何根据给定的概率选取一个数字。
答案 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。直方图显示它似乎正常工作。
我要做的另一个调整是为了让它能够处理更多通用输入,将第一行改为r = rand * sum(dist)
。这会自动规范化分布,因此它不必总和为1。