【问题标题】:Better coin toss with a draw?平局抛硬币更好?
【发布时间】:2020-11-23 16:24:39
【问题描述】:

我正在为我的聊天机器人构建一个抛硬币游戏,我认为将非常罕见的硬币落在它的一侧会很有趣。根据这篇文章,美国镍币的赔率大约是 6000 分之一:

基于该模型的推断表明,美国镍币落在边缘的概率约为 6000 次投掷中的 1 次。

我创建了一个可行的解决方案,但对一侧或另一侧来说很重,在我上次运行中,正面结果很重(从零到绘制的 3 次迭代中的前 10 个结果:11 个反面,19头):

Tails. Tails. Heads. Heads. Tails. Tails. Heads. Heads. Heads. - Toss 11666 was a draw.
Heads. Tails. Tails. Heads. Heads. Tails. Tails. Tails. Heads. - Toss 6135 was a draw.
Heads. Tails. Heads. Heads. Heads. Tails. Heads. Heads. Heads. - Toss 24100 was a draw.

此代码非常简单,尽管它允许绘制看似发生的频率低于大约 6,000 次迭代中的 1 次,因为随机使用了模数58006200 之间的数字:

int result = _random.Next(2);
if (++_tossCount % _random.Next(5800, 6200) == 0) {
    result = 2;
    _tossCount = 0;
}

switch (result) {
    case 0: return "Heads.";
    case 1: return "Tails.";
    default: return "It was a draw!";
}

_random_tossCount是类中的字段,分别在构造函数中初始化为new Random()0它们可以在开头初始化主,但在迭代器之外用于控制台应用程序中的复制目的)。上面的代码是一个返回 string 的方法,可以在您选择的迭代器中调用该方法来复制该过程。我使用do-while 进行测试,但for 可以正常工作。


如何提高在正面和反面之间平均分配结果的概率,以及大约每 6000 次调用获得平局的概率?

【问题讨论】:

  • 我不明白数字 5800 和 6200 是从哪里来的。
  • @RobertHarvey 它们是我选择的随机数,以增加获得平局的几率。本质上是为了防止每 6000 次迭代恰好发生一次平局。
  • 你不能选择一个介于 0 和 6000 之间的随机数吗?数字 0 - 2999 是正面,3000 - 5999 是反面,6000 是边(包括所有)。或者,从选择 1 到 6000 之间的数字开始:如果是 6000,那么您将获得优势。否则,为正面与反面选择一个介于 0 和 1 之间的数字。
  • (会在我离开会议后)
  • 要获得完全正确的赔率,需要 1 - 5999 正面、6000 -11998 反面和 11999 - 12000 平局。

标签: c# math probability


【解决方案1】:

要获得正确的赔率,您可以创建一个介于 1 到 12000 之间的随机数,其中各种结果由范围表示:

enum CoinTossResult { Heads, Tails, Draw };
CoinTossResult TossCoin()
{
    return _random.Next(1, 12000) switch
    {
        <= 5999 => CoinToss.Heads,
        <= 11998 => CoinToss.Tails,
        _ => CoinToss.Draw
    };
}

现在平局的概率是 6000 分之一。正面和反面平分 6000 分中剩余的 5999 个。


注意:使用的语法仅适用于C# 8 and higher

【讨论】:

  • 为了未来的读者,您介意包含使用 switch 表达式语法所需的 .NET 版本吗?我知道它在 C# 8 中,但其他读者可能不会因此而导致编译器错误。 :)
  • @Tacoタコス 好的,我已经添加了。
猜你喜欢
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-25
  • 2012-12-02
相关资源
最近更新 更多