如何解决固定数量实例的概率函数 实施
我需要构建一个布尔概率测试,该测试可以定期运行并增加返回 true 的机会。
返回阳性测试概率的增加由变量 (nMax) 决定,变量 (nMax) 表示返回 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()
解决方法
有无数种解决方案可以满足您的限制条件。一个简单的方法是要求每次运行具有相同成功的概率。我们称这个概率为?。
我们必须满足在第一次 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.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。