2010-10-21 7 views
7

Désolé, je suis nouveau à JS et ne peux pas sembler comprendre ceci: comment ferais-je la probabilité?probabilité en javascript aide?

Je n'ai absolument aucune idée, mais je voudrais faire quelque chose: sur 100% de chance, peut-être 0,7% de chance d'exécuter la fonction e(); et 30% de chance d'exécuter la fonction d(); et ainsi de suite - ils vont ajouter jusqu'à 100% exactement avec une fonction différente pour chacun, mais je n'ai pas compris exactement comment faire cela sous quelque forme que ce soit. Ce que j'ai trouvé est la plupart du temps des tutoriels mathématiques d'école secondaire étranges "actionnés par" Javascriptkit ou quelque chose.

+0

sont ces probabilités définies? comme dans, allez-vous avoir une table des probabilités qui lient à des fonctions? ou sont-ils dynamiques, basés sur l'entrée? –

+0

La probabilité est définie, avec une table liée à la fonction. – jen

Répondre

15

Par exemple on définit un certain nombre de fonctions

function a() { return 0; } 
function b() { return 1; } 
function c() { return 2; } 

var probas = [ 20, 70, 10 ]; // 20%, 70% and 10% 
var funcs = [ a, b, c ]; // the functions array 

Cette fonction générique fonctionne pour un certain nombre de fonctions, il l'exécute et renvoie le résultat:

function randexec() 
{ 
    var ar = []; 
    var i,sum = 0; 


    // that following initialization loop could be done only once above that 
    // randexec() function, we let it here for clarity 

    for (i=0 ; i<probas.length-1 ; i++) // notice the '-1' 
    { 
    sum += (probas[i]/100.0); 
    ar[i] = sum; 
    } 


    // Then we get a random number and finds where it sits inside the probabilities 
    // defined earlier 

    var r = Math.random(); // returns [0,1] 

    for (i=0 ; i<ar.length && r>=ar[i] ; i++) ; 

    // Finally execute the function and return its result 

    return (funcs[i])(); 
} 

Par exemple, nous allons essayer avec nos 3 fonctions, 100000: tries

var count = [ 0, 0, 0 ]; 

for (var i=0 ; i<100000 ; i++) 
{ 
    count[randexec()]++; 
} 

var s = ''; 
var f = [ "a", "b", "c" ]; 

for (var i=0 ; i<3 ; i++) 
    s += (s ? ', ':'') + f[i] + ' = ' + count[i]; 

alert(s); 

Le résultat sur mon Firefox

a = 20039, b = 70055, c = 9906 

Alors une course environ 20%, b ~ 70% et c ~ 10%.


Éditez après les commentaires.

Si votre navigateur a une toux avec return (funcs[i])();, il suffit de remplacer le tableau funcs

var funcs = [ a, b, c ]; // the old functions array 

avec ce nouveau (cordes)

var funcs = [ "a", "b", "c" ]; // the new functions array 

puis remplacer la dernière ligne de la fonction randexec()

return (funcs[i])(); // old 

avec ce nouveau

return eval(funcs[i]+'()'); 
+0

Pour une raison quelconque, il dit juste 'Erreur: funcs [i] n'est pas une fonction' (pour la ligne' return (funcs [i])(); ') après avoir ajouté mes propres arrs. Les tableaux count, probas et funcs sont tous très bien, et toutes les fonctions existent. Je ne suis pas sûr si avoir des numéros dans les noms de la fucntion et beaucoup de probabilités en double aurait de l'importance. – jen

+0

Etes-vous sûr de ne pas avoir créé un nom de fonction qui ne soit pas dans le tableau funcs, ou, par exemple, qu'un nom de fonction comme «i» interfère avec les autres variables? S'il vous plaît essayez avec mon exemple. Si cela fonctionne, il devrait fonctionner avec n'importe quelle fonction, tant que son nom est correct, est dans le tableau funcs et ne cache pas une autre variable existante (ou, inversement, serait caché par une autre variable). –

+0

S'il vous plaît vérifier mon ** edit ** il devrait fonctionner avec n'importe quel navigateur. (Le commentaire ci-dessus sur les variables qui se cachent est toujours vrai :-) –

1

On dirait que ce que vous voulez vraiment, c'est le Javascript random() function.

+0

S'IL VOUS PLAÎT, ne vous référez jamais à la documentation 'W3school', utilisez plutôt la documentation javascript officielle dans Mozilla https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random peut-être en 2010 cela n'existait pas? – ncubica

1

Cherchez comment obtenir des nombres aléatoires en JavaScript, puis en fonction de l'endroit où ce nombre tombe, appelez chaque fonction.

+0

J'ai regardé la fonction aléatoire, mais je ne pouvais pas vraiment comprendre exactement comment le faire parce qu'il retourne juste des nombres aléatoires et je n'ai aucune idée comment comparer 0,4% d'un nombre aléatoire ou quelque chose .. – jen

+1

Trouver un moyen d'obtenir un nombre aléatoire compris entre 1 et 10 inclus. Ensuite, vérifiez si le nombre est 1, 2 ou 3 afin de vérifier 30% des cas. – philfreo

+0

Je ne suis pas sûr de savoir si cela correspondrait au reste - il y a environ 25 fonctions qui sont inférieures à 0,5%. Dois-je plafonner ou plancher pour 1 et 10 ou est-ce que ce n'est pas important tant que c'est cohérent? – jen

4

Quelque chose comme cela devrait aider:

var threshhold1 = 30.5; 
var threshhold2 = 70.5; 
var randomNumber = random() * 100; 
if (randomNumber < threshhold1) { 
    func1() 
} 
else if (randomNumber < threshhold2) { 
    func2() 
} 
else { 
    func3() 
} 

Cela exécutera func1() avec 30,5% de probabilité, func2() avec 40%, et func3() avec 29,5%.

Vous pourriez probablement le faire plus élégamment en utilisant un dictionnaire de seuils pour fonctionner des pointeurs, et une boucle qui trouve la première entrée de dictionnaire avec un seuil supérieur à randomNumber.

+0

J'ai essayé quelque chose comme ça, mais je n'arrive pas à le faire fonctionner pour un très grand nombre de montants identiques (beaucoup de 0,50%) – jen

+0

Je pensais quelque chose comme <0.50, > 0,50 && <1.0, > 1 && <1,5, mais cela semble être inutilement compliqué s'il y avait un meilleur moyen – jen

+1

Il suffit de définir les seuils à 0.5, 1.0, 1.5, 2.0 , ... Vous devez seulement vérifier chaque seuil une fois car une fois qu'un seuil correspond à l'autre, les seuils les plus élevés ne seront pas vérifiés. –

0
var decide = function(){ 
    var num = parseInt(Math.random() * 10) + 1; // assigns num randomly (1-10) 
    num > 7 ? d() : e(); // if num > 7 call d(), else call e() 
}; 
1
// generate cumulative distribution function from weights 
function cdf(weights) { 
    // calculate total 
    var total = 0; 
    for(var i=0; i<weights.length; i++) { 
     total += weights[i]; 
    } 
    // generate CDF, normalizing with total 
    var cumul = []; 
    cumul[0] = weights[0]/total; 
    for(var i=1; i<weights.length; i++) { 
     cumul[i] = cumul[i-1] + (weights[i]/total); 
    } 
    return cumul; 
} 

// pick the index using the random value 
function selectInd(cumul,rand) { 
    for(var i=0; (i < cumul.length) && (rand > cumul[i]); ++i) {}; 
    return i; 
} 
Bloc de code

à utiliser ce qui précède

// setup (do this once) 
var weights = [70,20,10]; 
var cumul = cdf(weights) 

// get the index and pick the function 
var ran = Math.random(); // 0 : 1 
var func = funcs[selectInd(cumul,ran)]; 

// call the function 
var someArgVal = 5; 
var myResult = func(someArgVal); 

// do it in one line 
var myResult = (funcs[selectInd(cumul,Math.random())])(someArgVal); 

simplifier le code appelant avec un objet réutilisable

function CumulDistributor(cumul,funcs) { 
    var funcArr = funcs; 
    var cumulArr = cumul; 
    function execRandomFunc(someArg) { 
     var func = funcArr[selectInd(cumulArr,Math.random())]; 
     return func(someArg); 
    } 
} 

// example usage 
var cdistor = new CumulDistributor(cumul,funcs); 
var myResult = cdistor.execRandomFunc(someArgValue);