【问题标题】:Probability Function over a fixed number of instances固定数量实例上的概率函数
【发布时间】:2021-08-24 04:46:15
【问题描述】:

我需要构建一个布尔概率测试,该测试可以定期运行并增加返回 true 的机会。

返回阳性测试的概率增加由变量 (nMax) 确定,该变量表示返回 true 概率为 95% 以上的组合结果的预期测试次数。

例如:对于 nMax = 1000

n = [1] has 'almost zero' percent chance of returning true
n = [2] has 'slightly more than almost zero' percent chance of returning true
....
n = [1000] still only has a 'small' chance of returning true but the combined result of n[1] -> n[1000] is now > .95

我曾多次尝试使用概率对数标度,但均未成功,但似乎没有一个特别有希望。非常欢迎您的想法。

function test(n, nMax){
  let test = Math.random()
  if (Math.random() > (1/(n/nMax))){
    return true
  } else {
    return false
  }
}

function runUntilTrue(){
  let i = 1;
  let result = false;
  while (result == false){
    result = test(i, 100)
    i++
  }
  console.log(i + " tests until true was returned true")
}

runUntilTrue()

【问题讨论】:

  • 请在minimal reproducible example 上分享您目前的进展情况。
  • 添加了简单的框架 - 不拘泥于它
  • 我认为这个问题在数学领域而不是在计算机科学领域......我想像 (n / (nMax - n)) * (n / nMax) * 0.95 > Math.random() 这样的东西可能会起作用
  • 使用Math.random 检查非常低的概率(如Math.random() < 0.000001)可能会出现问题。为什么不只调用一次Math.random 来确定运行次数,而不是每次运行时调用它?
  • trincot 的回答似乎符合您的要求。如果您想要一个通过nth 调用(而不是 95% 的机会)返回 true 的函数,那么可能会这样做:const randomToN = (n, i = 1) => () => Math .random () < i++ / n 然后myRandom(1000) 是您的函数可以调用以取回布尔值。它将通过nth 调用返回true(然后永远返回。)

标签: javascript algorithm probability


【解决方案1】:

有无数种解决方案可以满足您的限制条件。一个简单的方法是要求每次运行都有相同 的成功概率。我们称这个概率为?。

我们必须满足在第一次 nMax 运行中获得成功的概率是 0.95。换句话说,在第一次 nMax 运行中没有成功的概率是 0.05。

第一次运行没有成功,概率为 1 - ?。在第一次和第二次运行中均未成功,概率为 (1 - ?)²。在前 nMax 次运行中没有获得成功的概率为 (1 - ?)nMax

让我们解决这个问题:

     (1 − ?)nMax = 0.05

所以:

     ? = 1 − 0.051/nMax

实施

function neededRuns(nMax, cumulProb=0.95) {
    const p = 1 - (1 - cumulProb) ** (1/nMax);
    
    let n = 1;
    while (Math.random() >= p) n++;
    return n;
}

// Test
const nMax = 100;
const cumulProb = 0.95;
const numAttempts = 100;

let numExceeding = 0;
for (let attempt = 0; attempt < numAttempts; attempt++) {
    let runCount = neededRuns(nMax, cumulProb); 
    console.log(runCount);
    if (runCount > nMax) numExceeding++;
}

console.log(`${numExceeding}/${numAttempts} attemps needed more than ${nMax} runs.`);  

严格递增系列

如果您希望个体概率严格增加,那么您可以应用类似的策略,但人为地稍微降低概率,然后重新计算 nMax-1 的平均概率,然后重复。

您可以为此使用迭代器:

function * iterProbability(nMax, cumulProb=0.95) {
    let failProb = 1 - cumulProb;
    let p, prevP;
    while (nMax) {
        prevP = p;
        p = 1 - failProb ** (1/nMax);
        nMax--;
        p *= 0.99 ** nMax; // reduce p a bit
        yield p;
        failProb /= 1 - p;  // take this p into account for next iteration
    }
    // After nMax probabilities, 
    //   continue with the same factor of reduction of failure probability
    let coeff = (1 - p) / (1 - prevP);
    while (true) { // ...for ever.
        p = 1 - (1 - p) * coeff;
        yield p;
    }
}

function neededRuns(nMax, cumulProb=0.95) {
    let n = 0;
    for (let p of iterProbability(nMax, cumulProb)) {
        n++;
        if (Math.random() < p) return n;
    }
}

// Test
const nMax = 100;
const cumulProb = 0.95;
const numAttempts = 100;

let numExceeding = 0;
for (let attempt = 0; attempt < numAttempts; attempt++) {
    let runCount = neededRuns(nMax, cumulProb); 
    console.log(runCount);
    if (runCount > nMax) numExceeding++;
}

console.log(`${numExceeding}/${numAttempts} attemps needed more than ${nMax} runs.`);
// Be aware that Stack Snippets clip the console ouput.

【讨论】:

  • 我同意这个问题的约束不足,但 OP 说(或似乎说) P(1)
  • @RobertDodier,我添加了一个严格增加 P(k) 的变体脚本。
猜你喜欢
  • 2011-05-03
  • 2018-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多