【问题标题】:How to make probability increase over time with predictable outcome如何以可预测的结果使概率随着时间的推移而增加
【发布时间】:2013-10-26 21:57:42
【问题描述】:

我有一个由机器人玩的游戏程序。为简单起见,游戏有 2 个按钮——“赢”和“再试一次”。要获胜,机器人必须简单地按下“获胜”按钮。

游戏包含一个倒数计时器,它从 10 开始并运行到 0,每秒滴答一次。在计时器的每个滴答声中,机器人都会选择两个按钮中的一个。当计时器为 10 时,机器人点击获胜的机会非常小。随着计时器接近 0,机器人点击“获胜”按钮的机会增加。当然,机器人可能根本不会点击获胜按钮。

我最终要寻找的是机器人在大约 90% 的时间里点击“获胜”,而这些获胜点击的权重更接近计时器为 0。

我对概率进行了一些研究(绝对新手),我的理解是每次滴答的概率总和应该达到 0.90,才能得到我想要的结果。示例:

countdownTimerTickNumber | probabilityOfClickingWin
====================================================
10 | 0
9 | 0.0001
8 | 0.005
7 | 0.01
6 | 0.02
5 | 0.04
4 | 0.08
3 | 0.1
2 | 0.15
1 | 0.2
0 | 0.294
----------------------------------
Total probabilityOfClickingWin over all ticks: .9

这里有一些伪代码,展示了我如何使用上表中的概率来实际确定机器人点击了哪个按钮。它在每个滴答声中被调用:

function bool doClickWin(probabilityOfClickingWin)
{
     if (probabilityOfClickingWin >= new Random().NextDouble())
          return true;

     return false;
}

但是,如果我多次运行我的程序,我会发现机器人点击“获胜”的实际百分比远低于 90%(大约 60%)。

谁能告诉我我做错了什么?提前致谢。

【问题讨论】:

  • 我删除了我的评论,因为它不准确但想法是正确的。搞砸你的逻辑的是probabilityOfClickingWin 和它的计算方式。要获得所需的概率,它需要是probability * maxRandomNumberThatCanBeReturned。由于Random.NextDouble 返回最大值1.0d,您需要通过0.9d 才能获得90% 的返回true。这是示例:ideone.com/a8wxw6 更高的尝试更准确成为结果。同时保持Random对象静态(reason
  • Leri - 看起来您的示例中的 CompareWithRandom() 将在“尝试”的每次迭代中返回 true 约 90% 的时间。这实际上不是我需要的。我需要它,以便对于组合的所有“尝试”迭代,CompareWithRandom() 仅返回一次 true 的可能性约为 90%。不过,感谢您抽出宝贵时间。

标签: c# statistics probability


【解决方案1】:

概率计算比你想象的要复杂。中奖概率为

P(win on 0th tick) + P(win on 1st tick) + ... + P(win on 10th tick)

我们将概率称为 p(0) ... p(11)。那么

P(win on 0th tick) = p(0)
P(win on 1st tick) = (1-p(0)) * p(1)
P(win on 2nd tick) = (1-p(0)) * (1-p(1)) * p(2)

等等。在每个滴答中,您在该滴答中获胜的概率是您在之前的任何滴答中尚未获胜的概率乘以现在获胜的概率。

根据您在帖子中提供的数字,我认为您的机器人应该赢得大约 63.17% 的时间(我不确定您为什么看到大约 30% - 这可能是您程序中的其他地方的错误吗?)

通过以下数字,您应该观察到总体成功率约为 90%

 0       0
 1  0.0068
 2  0.0113
 3  0.0188
 4  0.0314
 5  0.0524
 6  0.0875
 7  0.1459
 8  0.2433
 9  0.4059
10  0.6771

编辑

我是如何得出这些数字的?反复试验。但是我们可以发明一个程序,给定任何获胜概率,为每个报价生成一组合适的概率。

假设总获胜概率是Q,所以你想要

P(Win on 0th tick) + ... + P(Win on 10th tick) = Q

假设我们希望在第一个刻度上没有获胜的机会,并且在之后的任何刻度上都线性增加获胜的机会。所以概率必须加起来为 Q,并且在滴答声i 时获胜的概率与i 成正比。因此

P(Win on ith tick) = const * i

因此

   c * 0 + c * 1 + c * 2 + ... + c * 10 = Q

=> 55 * c = Q

=> c = Q/55

这给了我们

P(Win on 0th tick) = 0
P(Win on 1st tick) = Q/55
P(Win on 2nd tick) = 2*Q/55

等等。现在,您使用这些来确定每个 p(i) 使用帖子顶部的公式。我们有

p(0) = P(win on 0th tick) = 0
p(1) = P(win on 1st tick) / (1-p(0)) = Q/55
p(2) = P(win on 2nd tick) / (1-p(0)) / (1-p(1)) = 2*(Q/55) / (1-Q/55)

等等。这是一个计算概率的 Matlab 例程;将它翻译成 C# 或您正在使用的任何东西应该不难。

N = 10;
Q = 0.9;
p = zeros(N+1,1);

for i = 1:N
  p(i+1) = i * Q/(0.5*N*(N+1)) / prod(1-p(1:i));
end

给出这个结果

 0         0
 1    0.0164
 2    0.0333
 3    0.0516
 4    0.0726
 5    0.0978
 6    0.1301
 7    0.1745
 8    0.2416
 9    0.3584
10    0.6207

【讨论】:

  • 你说得对,我得到了 ~60%。看起来您看到了我的问题,但是您能向我解释一下或给我一个确切的公式,说明您是如何获得每个刻度的一组概率的吗?实际上有很多机器人,它们有不同的概率(不仅仅是 90%),所以我需要能够从机器人的总概率倒推,以确定每个机器人在每个滴答声中的概率。我试图用你的 sn-p 来解决这个问题,但我被卡住了(例如P(win on 1st tick) = (1-p(0)) * p(1) - 但P(win on 1st tick)p(1) 在这一行中不一样吗?)。再次感谢。
  • 概率p(i) 是您在此滴答中获胜的概率,如果我们达到它。但是您并不总是达到那个滴答,因为您可能会在较早的滴答中获胜。概率P(Win on ith tick) 是您的机器人在第 i 个滴答声中获胜的总概率。这些是互斥的,因此可以将它们相加以获得总获胜概率。
  • 我在帖子中得出数字的方式只是反复试验。我将进行编辑,为您提供一个更具体的程序来确定每个刻度的概率。
  • 感谢您的努力。在您处理它时,让我澄清一下可用于公式的两条数据:1)所有刻度的总概率(例如 90%、85%、70% 等)和 2)公式设置每个刻度的概率的曲线:y = x^2.25(x 是刻度编号,y 是刻度的相对概率。换句话说,随着 x 的增加,它是“获胜刻度”的概率也会增加。希望这是'不要太混乱)。
  • 对不起,我忘记了另一条数据:3) 滴答总数。我说在原始问题中为简单起见始终为 10,但实际上它可能因游戏而异。我继续并已经将您的答案标记为正确,因为这些是附加参数,但我希望您仍然可以为所有这些提出一个公式。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-22
  • 1970-01-01
  • 2015-06-01
相关资源
最近更新 更多