Je veux générer un nombre aléatoire avec une probabilité donnée mais je ne sais pas comment:
J'ai besoin d'un nombre entre 1 et 3
num = ceil(Rand*3);
mais j'ai besoin de valeurs différentes pour avoir différentes probabilités de générer par exemple.
0.5 chance of 1
0.1 chance of 2
0.4 chance of 3
Je suis sûr que c'est simple mais je ne peux pas penser à comment le faire.
La solution simple est de générer un nombre avec une distribution uniforme (en utilisant Rand
), et de le manipuler un peu:
r = Rand;
prob = [0.5, 0.1, 0.4];
x = sum(r >= cumsum([0, prob]));
ou en monoplace:
x = sum(Rand >= cumsum([0, 0.5, 0.1, 0.4]));
Ici r
est un nombre aléatoire uniformément réparti entre 0 et 1. Pour générer un nombre entier entre 1 et 3, l'astuce consiste à diviser la plage [0, 1] en 3 segments, où la longueur de chaque segment est proportionnelle à sa probabilité correspondante. Dans votre cas, vous auriez:
La probabilité que r
tombe dans l'un des segments est proportionnelle aux probabilités que vous souhaitez pour chaque nombre. sum(r >= cumsum([0, prob]))
n'est qu'un moyen sophistiqué de mapper un nombre entier à l'un des segments.
Si vous souhaitez créer un vecteur/matrice de nombres aléatoires, vous pouvez utiliser une boucle ou arrayfun
:
r = Rand(3); % # Any size you want
x = arrayfun(@(z)sum(z >= cumsum([0, prob])), r);
Bien sûr, il y a aussi une solution vectorisée, je suis juste trop paresseux pour l'écrire.
Jusqu'à présent, les réponses sont correctes, mais lentes pour les entrées de grande taille: O (m * n) où n est le nombre de valeurs et m est le nombre d'échantillons aléatoires. Voici une version O (m * log (n)) qui tire parti de la monotonie du résultat cumsum
et de la recherche binaire utilisée dans 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
distribué comme vous le souhaitez.
en utilisant la fonction randsample
de Statistics and Machine Learning Toolbox, vous pouvez générer des nombres aléatoires avec une fonction de masse de probabilité spécifiée (pmf):
pmf = [0.5, 0.1, 0.4];
population = 1:3;
sample_size = 1;
random_number = randsample(population,sample_size,true,pmf);
Je pense que c'est la méthode la plus simple.
Une solution un peu plus générale serait:
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)