2012-01-16 11 views
17

Estoy un poco confundido acerca de cómo generar valores enteros con probabilidades. ser claro como un ejemplo,generar enteros aleatorios con probabilidades

Tengo cuatro números enteros con sus valores de probabilidad: 1 | 0,4, 2 | 0,3, 3 | 0,2, 4 | 0.1

¿Cómo puedo generar estos cuatro números teniendo en cuenta su probabilidades?

La implementación de JavaScript sería apreciada.

+0

Si quieres saber un montón de detalles técnicos acerca de cómo hacer esto de manera rápida, esto es un gran recurso. Para hacer una elección ponderada entre 4 opciones, sin embargo, es totalmente innecesario. http://www.keithschwarz.com/darts-dice-coins/ –

+0

Vea también http://stackoverflow.com/questions/3094873 – Lucas

Respuesta

28

Aquí hay un truco útil :-)

function randomWithProbability() { 
    var notRandomNumbers = [1, 1, 1, 1, 2, 2, 2, 3, 3, 4]; 
    var idx = Math.floor(Math.random() * notRandomNumbers.length); 
    return notRandomNumbers[idx]; 
} 
+2

Dirección correcta, simplemente cree 'notRandomNumbers' dinámicamente (dados los números y su peso/probabilidad) y es la solución ideal en mi opinión. –

+0

¡Agradable! Gracias. esto se ve justo lo que necesito. – Headshota

+0

@ShadowWizard: sí, lo hice simple por claridad :-) –

21

Un enfoque ingenuo simple puede ser:

function getRandom(){ 
    var num=Math.random(); 
    if(num < 0.3) return 1; //probability 0.3 
    else if(num < 0.6) return 2; // probability 0.3 
    else if(num < 0.9) return 3; //probability 0.3 
    else return 4; //probability 0.1 
}

+0

¿Qué pasa si dos números tienen la misma probabilidad? :-) –

+1

la lógica seguirá siendo la misma. ver la edición. – bhups

8

solución más flexible basado en @bhups respuesta. Esto usa la matriz de valores de probabilidad (pesos). La suma de elementos 'pesos' debe ser igual a 1.

var weights = [0.3, 0.3, 0.3, 0.1]; // probabilities 
var results = [1, 2, 3, 4]; // values to return 

function getRandom() { 
    var num = Math.random(), 
     s = 0, 
     lastIndex = weights.length - 1; 

    for (var i = 0; i < lastIndex; ++i) { 
     s += weights[i]; 
     if (num < s) { 
      return results[i]; 
     } 
    } 

    return results[lastIndex]; 
}; 
2

Sugiero utilizar una verificación continua de la probabilidad y el resto del número aleatorio.

Esta función establece primero el valor de retorno al último índice posible y lo itera hasta que el resto del valor aleatorio sea menor que la probabilidad real.

Las probabilidades tienen que sumar a una.

function getRandomIndexByProbability(probabilities) { 
 
    var r = Math.random(), 
 
     index = probabilities.length - 1; 
 

 
    probabilities.some(function (probability, i) { 
 
     if (r < probability) { 
 
      index = i; 
 
      return true; 
 
     } 
 
     r -= probability; 
 
    }); 
 
    return index; 
 
} 
 

 
var i, 
 
    probabilities = [0.4, 0.3, 0.2, 0.09, 0.01 ], 
 
    count = {}, 
 
    index; 
 

 
probabilities.forEach(function (a) { count[a] = 0; }); 
 

 
for (i = 0; i < 1e6; i++) { 
 
    index = getRandomIndexByProbability(probabilities); 
 
    count[probabilities[index]]++ 
 
} 
 

 
console.log(count);

Cuestiones relacionadas