Generar números aleatorios con probabilidad dada matlab

Resuelto Eamonn McEvoy asked hace 12 años • 7 respuestas

Quiero generar un número aleatorio con una probabilidad determinada pero no estoy seguro de cómo hacerlo:

necesito un numero entre 1 y 3

num = ceil(rand*3);

pero necesito valores diferentes para tener diferentes probabilidades de generar, por ejemplo.

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

Estoy seguro de que esto es sencillo, pero no se me ocurre cómo hacerlo.

Eamonn McEvoy avatar Dec 17 '12 19:12 Eamonn McEvoy
Aceptado

La solución simple es generar un número con una distribución uniforme (usando rand) y manipularlo un poco:

r = rand;
prob = [0.5, 0.1, 0.4];
x = sum(r >= cumsum([0, prob]));

o en una sola línea:

x = sum(rand >= cumsum([0, 0.5, 0.1, 0.4]));

Explicación

Aquí rhay un número aleatorio distribuido uniformemente entre 0 y 1. Para generar un número entero entre 1 y 3, el truco consiste en dividir el rango [0, 1] en 3 segmentos, donde la longitud de cada segmento es proporcional a su probabilidad correspondiente. . En tu caso tendrías:

  • Segmento [0, 0,5), correspondiente al número 1.
  • Segmento [0.5, 0.6), correspondiente al número 2.
  • Segmento [0.6, 1], correspondiente al número 3.

La probabilidad de rcaer dentro de cualquiera de los segmentos es proporcional a las probabilidades que desea para cada número. sum(r >= cumsum([0, prob]))es sólo una forma elegante de asignar un número entero a uno de los segmentos.

Extensión

Si está interesado en crear un vector/matriz de números aleatorios, puede usar un bucle o arrayfun:

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

Por supuesto, también hay una solución vectorizada, pero soy demasiado vago para escribirla.

Eitan T avatar Dec 17 '2012 12:12 Eitan T

Las respuestas hasta ahora son correctas, pero lentas para entradas grandes: O(m*n) donde n es el número de valores y m es el número de muestras aleatorias. Aquí hay una versión O(m*log(n)) que aprovecha la monotonicidad del cumsumresultado y la búsqueda binaria utilizada en histc:

% assume n = numel(prob) is large and sum(prob) == 1
r = rand(m,1);
[~,x] = histc(r,cumsum([0,prob]));
Alec Jacobson avatar Dec 04 '2013 12:12 Alec Jacobson