Sorry, I\'m new to JS and can\'t seem to figure this out: how would I do probability?
I have absolutely no idea, but I\'d like to do something: out of 100% chance, m
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()
};
Something like this should help:
var threshhold1 = 30.5;
var threshhold2 = 70.5;
var randomNumber = random() * 100;
if (randomNumber < threshhold1) {
func1()
}
else if (randomNumber < threshhold2) {
func2()
}
else {
func3()
}
This will execute func1()
with 30.5% probability, func2()
with 40%, and func3()
with 29.5%.
You could probably do it more elegantly using a dictionary of threshholds to function pointers, and a loop that finds the first dictionary entry with a threshhold greater than randomNumber
.
Sounds like what you really want is the Javascript random() function.
Look up how to get random numbers in JavaScript, and then depending on where that number falls, call each function.
// 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;
}
Code block to use the above
// 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);
Simplify calling code with a reusable object
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);
For instance we define a number of functions
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
That generic function works for any number of functions, it executes it and return the result:
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])();
}
For instance, let's try with our 3 functions, 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);
The result on my Firefox
a = 20039, b = 70055, c = 9906
So a run about 20%, b ~ 70% and c ~ 10%.
Edit following comments.
If your browser has a cough with return (funcs[i])();
, just replace the funcs array
var funcs = [ a, b, c ]; // the old functions array
with this new one (strings)
var funcs = [ "a", "b", "c" ]; // the new functions array
then replace the final line of the function randexec()
return (funcs[i])(); // old
with that new one
return eval(funcs[i]+'()');