2010-10-21 2 views
7

Извините, я новичок в JS и не могу понять, как это сделать: как я могу сделать вероятность?вероятность использования javascript?

У меня нет абсолютно никакой идеи, но я хотел бы что-то сделать: из 100% шансов, возможно 0,7% шанс выполнить функцию e(); и 30% шанс выполнить функцию d(); и так далее - они будут содержать до 100% точно с другой функцией для каждого, но я не понял точно, как это сделать в любой форме.

Что я нашел, это в основном странные учебные пособия средней школы по математике "powered by" Javascriptkit или что-то в этом роде.

+0

эти наборы вероятности? как, например, у вас будет таблица вероятностей, которая ссылается на функции? или они динамичны на основе ввода? –

+0

Устанавливается вероятность, с таблицей, которая ссылается на функцию. – jen

ответ

15

Например, мы определим ряд функций

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 

Это общая функция работает для любого числа функций, она выполняет его и возвращает результат:

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])(); 
} 

Например, давайте попробуем с наши 3 функции, 100000 попыток:

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); 

Результат на моем Firefox

a = 20039, b = 70055, c = 9906 

Так перспективе около 20%, б ~ 70% и с ~ 10%.


Редактировать следующие комментарии.

Если ваш браузер имеет кашель с return (funcs[i])();, просто замените массив funcs

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

с этим новым (строк)

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

замените последнюю строку функции randexec()

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

с этим новым один

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

По какой-то причине он просто говорит: 'Ошибка: funcs [i] не является функцией' (для строки 'return (funcs [i])();') после добавления моих собственных arr. Массивы count, probas и funcs все в порядке, и все функции существуют. Не уверен, имеет ли значение число в именах fucntion и LOT дублированных вероятностей. – jen

+0

Вы уверены, что не создали имя функции, которое не находится в массиве funcs, или, например, что имя func, подобное 'i', мешает другим переменным? Пожалуйста, попробуйте мой пример. Если он работает, он должен работать с любой функцией, если имя правильное, находится в массиве funcs и не скрывает другую существующую переменную (или, наоборот, будет скрыта другой переменной). –

+0

Пожалуйста, проверьте мои ** править ** он должен работать с любым браузером. (приведенный выше комментарий о скрытии переменных по-прежнему верен :-) –

1

Похоже, что вы действительно хотите, это Javascript random() function.

+0

ПОЖАЛУЙСТА, ПОЖАЛУЙСТА, никогда не обращайтесь к «документации W3school», используйте вместо этого официальную документацию по JavaScript в Mozilla https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random может быть, в 2010 году этого не было? – ncubica

1

Посмотрите, как получить случайные числа в JavaScript, а затем в зависимости от того, где это число падает, вызовите каждую функцию.

+0

Я посмотрел на случайную функцию, но я не мог понять, как именно это сделать, потому что он просто возвращает случайные числа, и я не знаю, как сравнить 0,4% от случайного числа или что-то в этом роде. – jen

+1

Найти способ получить случайное целое число от 1 до 10 включительно. Затем проверьте, есть ли число 1, 2 или 3, чтобы проверить на 30% случаев. – philfreo

+0

Я не уверен, как это поместится с остальными, хотя есть около 25 функций, которые составляют менее 0,5%. Должен ли я покрывать или пол для 1 и 10, или это не имеет значения, поскольку это непротиворечиво? – jen

4

Что-то, как это должно помочь:

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

Это будет выполнять func1() с 30,5% вероятностью, func2() с 40%, и func3() с 29,5%.

Возможно, вы могли бы сделать это более элегантно, используя словарь порогов для указателей функций, и цикл, который находит первую запись словаря с порогом, превышающим randomNumber.

+0

Я пытался что-то вроде этого, но я не могу заставить его работать для очень большого количества одинаковых сумм (много 0.50%) – jen

+0

Я думал что-то вроде <0.50, > 0.50 && <1.0, > 1 && <1.5, но похоже, что было бы излишне сложно, если бы был лучший способ – jen

+1

Просто установите пороговые значения в 0.5, 1.0, 1.5, 2.0 , .... Вам нужно только проверить каждый порог один раз, потому что, как только один столбец будет соответствовать другим, более высокие пороги не будут проверены. –

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; 
} 

блоком коды использовать вышеуказанный

// 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 вызывающего код с многоразовым объектом

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); 
Смежные вопросы