Элегантный способ смещения случайных логических - PullRequest
5 голосов
/ 05 сентября 2010

Я хотел бы создать случайное логическое значение в JavaScript, но я хочу принять во внимание предыдущее значение.Если предыдущее значение было истинным, я бы хотел, чтобы следующее значение было истинным.На данный момент у меня есть это (это в контексте замыкания - goUp и lastGoUp являются локальными объектами для содержащей области):

function setGoUp() {
    goUp = getRandomBoolean();

    if(lastGoUp) {
        goUp = getRandomBoolean() || goUp;
    }
    else {
        goUp = getRandomBoolean() && goUp;
    }
    lastGoUp = goUp;
}

Итак, алгоритм идет:

  1. Получить случайное логическое значение
  2. Если случайное логическое значение из предыдущего вызова было True:

    a) получить другое случайное логическое значение, и or эти двавместе

    б) еще получить еще один случайный логический код и and вместе.

Я уверен, что этот алгоритм можно упростить.Я задавался вопросом:

if(lastGoUp && goUp) {
    goUp = goUp * (getRandomBoolean() || goUp);
}

, но это кажется действительно грязным.

Есть также проблема с этим алгоритмом, который означает, что я могу только удвоить шанс получить тот же логический код снова - яне могу легко его настроить.Есть идеи?

Ответы [ 5 ]

11 голосов
/ 05 сентября 2010

Вы должны определить дистрибутив, который хотите, но, возможно, вы ищете следующее?

if (lastGoUp) {
    goUp = Math.random() < 0.8;
} else {
    goUp = Math.random() < 0.2;
}
4 голосов
/ 05 сентября 2010

Вместо того, чтобы получить случайное логическое значение, получите случайное число, скажем, от 0 до 99. Сохраните пороговое значение вместо последнего и настройте пороговое значение в соответствии с результатом:

var threshold = 50;

function setGoUp() {
   goUp = getRandomNumber() < threshold;
   threshold += goUp ? -10 : 10;
}

При этом будет продолжена вкладка, поэтому, если вы получите последовательные одинаковые результаты, вероятность будет продолжать падать для этого результата.

Если вы хотите учесть только последний результат, вместо этого вы должны установить пороговое значение на конкретное значение:

threshold = goUp ? 40 : 60;
2 голосов
/ 05 сентября 2010

Если вы хотите, чтобы вероятность следующего события зависела от текущего значения, а не от истории значений до настоящего времени, то, что вы хотите, называется марковским процессом.Часто они реализуются с помощью двумерной таблицы вероятностей, которую вы просматриваете (вероятность каждого следующего результата, данного текущего), но для простого бул-значимого события достаточно оператора if (см. Ответ меритона; обратите внимание, что он соответствуеттаблица вероятностей [0,8 0,2; 0,2 0,8]).

Если вы хотите что-то, что становится более вероятным, скажем, чем больше успехов вы получаете подряд, то вам необходимо разработать последовательность вероятностей для успеха, котораявозможно, подходит, но не превосходит, 1. Существует несколько формул, которые могут это сделать, в зависимости от того, насколько сильным вы хотите стать смещением и как быстро вы хотите, чтобы оно достигло этого.

0 голосов
/ 05 сентября 2010

Может заменить Math.random для лучшего рандомизатора.

var setGoUp = (function(){
   var last;
   return function(){
       // if last 66% chance for true else 50% chance of true.
       return !!(last ? Math.random()*3 : Math.random()*2);
   }
}());

!!преобразует что-либо в логическое значение, 0 = false.

0 голосов
/ 05 сентября 2010

Я бы просто сделал вероятность получения значения true явной float переменной p. Тогда я мог бы легко настроить его, увеличив p некоторым образом, если я получил true в прошлый раз, или ничего не делая с ним, если я получил 'false'.

...