2012-01-16 22 views
17

Sono un po 'confuso su come generare valori interi con probabilità. essere chiaro come esempio,genera numeri interi casuali con probabilità

Ho quattro interi con i loro valori di probabilità: 1 | 0.4, 2 | 0.3, 3 | 0,2, 4 | 0.1

Come si genera questi quattro numeri tenendo conto della loro le probabilità?

l'implementazione javascript sarebbe apprezzata.

+0

Se vuoi sapere un sacco di dettagli tecnici su come farlo in fretta, questa è una grande risorsa. Per fare una scelta ponderata tra 4 scelte, è totalmente inutile però. http://www.keithschwarz.com/darts-dice-coins/ –

+0

Consulta anche http://stackoverflow.com/questions/3094873 – Lucas

risposta

28

Ecco un trucco utile :-)

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

Direzione corretta, crea semplicemente 'notRandomNumbers' in modo dinamico (dati i numeri e il loro peso/probabilità) ed è la soluzione ideale secondo me. –

+0

Bello! Grazie. questo sembra proprio quello di cui ho bisogno. – Headshota

+0

@ShadowWizard: sì, l'ho reso semplice per chiarezza :-) –

21

Un semplice approccio naive può essere:

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

Cosa succede se due numeri hanno la stessa probabilità? :-) –

+1

logica rimarrà lo stesso. vedi la modifica. – bhups

8

soluzione più flessibile basata su @bhups risposta. Questo utilizza la matrice di valori di probabilità (pesi). La somma degli elementi "pesi" dovrebbe essere uguale 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

Suggerisco di utilizzare un controllo continuo della probabilità e il resto del numero casuale.

Questa funzione imposta prima il valore di ritorno all'ultimo indice possibile e itera finché il resto del valore casuale è minore della probabilità effettiva.

Le probabilità devono essere sommate 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);

Problemi correlati