【问题标题】:Elegant way to bias random boolean偏向随机布尔值的优雅方法
【发布时间】:2011-04-08 10:33:44
【问题描述】:

我想在 JavaScript 中创建一个随机布尔值,但我想考虑以前的值。如果前一个值为真,我希望下一个值更有可能为真。目前我得到了这个(这是在闭包的上下文中 - goUplastGoUp 是包含范围的本地人):

function setGoUp() {
    goUp = getRandomBoolean();

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

所以,算法是这样的:

  1. 获取随机布尔值
  2. 如果上一次调用的随机布尔值为 True:

    a) 获取另一个随机布尔值,并将 or 这两个放在一起

    b) 否则得到另一个随机布尔值和and 这些在一起。

我确信这个算法可以简化。我想知道做什么:

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

但这看起来真的很脏。

这个算法还有一个问题,这意味着我只能将再次获得相同布尔值的机会加倍 - 我不能轻易调整它。有什么想法吗?

【问题讨论】:

    标签: javascript algorithm random boolean


    【解决方案1】:

    您应该定义您想要的分布,但也许您正在寻找以下内容?

    if (lastGoUp) {
        goUp = Math.random() < 0.8;
    } else {
        goUp = Math.random() < 0.2;
    }
    

    【讨论】:

    • 当然!我没有从任何偏见开始,所以我试图找出如何对预先存在的布尔值进行偏见。谢谢:)
    • 顺便说一句,我决定选择&lt; 0.8&gt; 0.8,因为这对我来说更有意义。将 0.8 变成命名常量也更清楚。
    • GetRandomFloatBetween0And1(即在区间[0, 1))正是Math.random()所做的。
    【解决方案2】:

    如果您只希望下一个事件的概率取决于当前值,而不是到目前为止的值的历史记录,那么您想要的称为马尔可夫过程。通常这些是通过您查找的 2D 概率表来实现的(给定当前结果的每个下一个结果的概率),但是对于简单的布尔值事件,if 语句就足够了(请参阅 Meriton 的答案;请注意,它对应于概率表 [0.8 0.2; 0.2 0.8])。

    如果您希望某件事情变得更有可能,例如,您连续获得的成功越多,那么您需要设计一系列可能接近但不超过 1 的成功概率。有任意数量的可以做到这一点的公式,取决于您希望偏见变得多强以及您希望它以多快的速度到达那里。

    【讨论】:

    • 旧的解决方案确实有效,因为我每次都生成两个随机布尔值。如果lastGoUptrue,那么我将ord 两个布尔值放在一起(四分之一的机会也为真),如果lastGoUpfalseand将两个布尔值放在一起(1 in 4 机会也是错误的)。这是一个相当混乱的算法。
    • 啊,我明白了,你是对的 - 所以这实际上是在做类似 [.75 .25; .25 .75]。我删除了我的断言,那是行不通的。
    【解决方案3】:

    可以替换 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。

    【讨论】:

      【解决方案4】:

      获取随机数而不是随机布尔值,例如 0 到 99 之间。保留阈值而不是最后一个数字,并根据结果调整阈值:

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

      这将保持一个正在运行的选项卡,因此如果您获得相同的连续结果,那么该结果的概率将继续下降。

      如果您只想考虑最后一个结果,您可以将阈值设置为特定值:

      threshold = goUp ? 40 : 60;
      

      【讨论】:

      • 谢谢。如果我需要考虑多个结果,我一定会牢记这一点。
      【解决方案5】:

      我只是将获得价值true 的概率设为显式float 变量p。然后我可以轻松地调整它,如果我上次得到true,则以某种方式增加p,或者如果我得到'false',则不做任何事情。

      【讨论】:

        猜你喜欢
        • 2019-11-03
        • 2013-06-25
        • 2013-10-12
        • 2015-12-29
        • 2012-01-15
        • 1970-01-01
        • 2014-06-13
        相关资源
        最近更新 更多