【问题标题】:Random number generator repeates some numbers too often随机数生成器过于频繁地重复某些数字
【发布时间】:2016-05-09 07:14:05
【问题描述】:

我正在编写一个抽奖模拟程序作为一个项目。游戏的运作方式是您需要从 49 中抽取 6 个号码来获胜。

您获胜的机会是 1/13,983,816,因为这就是 49 中 6 的组合数。 demo program on Go playground 每次在循环中生成六个新数字。

每次生成一组新数字时,我都会测试它是否已经存在,如果存在,我会跳出循环。对于 13,983,816 种组合,您会认为相同的 6 个数字重复出现需要很长时间,但是在测试中它总是在 10000 次迭代之前失败。有谁知道为什么会这样?

【问题讨论】:

  • 听起来您使用的是标准随机数生成器。虽然这是 PHP - 我建议查看有关 PHP.php.net/docs.php 中使用的两种随机数生成器的文章。寻找 rand 和 mt_rand。您可能还想查看stackoverflow.com/questions/4720822/…。这可能与您所询问的内容重复。

标签: arrays math random go generator


【解决方案1】:

在我看来,您在这里有几个问题。

  1. 您使用的是 Go 游乐场,其中您的随机性是固定的。这行rand.Seed(time.Now().UnixNano()) 总是产生相同的种子,因为time.Now() 是相同的。
  2. 您使用模拟测试完全不同的东西。我会写到最后。
  3. 如果你想做类似赌博的事情 - 你必须使用cryptographically secure PRNGGo has it。如果您愿意,可以阅读more details here(答案是 php 问题,但它解释了区别)。

关于概率部分:

中奖概率确实是1/C(49, 6) = 1/13,983,816。但这是有人会选择一组已经预定义的数字的概率。例如,您声称您的获胜者是{1, 5, 47, 3, 4, 5},而现在有人获胜的概率约为 1400 万分之一。因此,您必须执行以下操作。随机选择一组 6 个数字,然后在循环中将新选择的数字与已找到的数字进行比较。

但是你要做的是检查碰撞的概率。有 N 个人,其中一些人会选择相同的集合(不一定是获胜的集合)。这被称为birthday paradox。正如你所看到的,碰撞的概率随着人数 N 的增加而急剧增加。

这绝对是同一个问题,但是你一年中的天数是13,983,816,你可以check here,对于这个天数,你只需要 5000 次迭代就可以保证你会遇到 0.59% 的冲突.通过 9000 次迭代,您会发现碰撞概率为 0.94。

【讨论】:

  • --大理,“关于概率”。
【解决方案2】:

我相信您正在解决一个不同的问题,出现两个相同抽奖的可能性远高于出现一个特定抽奖的可能性。

这被称为Birthday Problem

【讨论】:

    【解决方案3】:

    顺便说一句,生日悖论的粗略经验法则是,如果你有 N 天,你需要迂回的 sqrt(N) 人来获得一个很好的碰撞机会(大约 50%)。

    所以,对于最初的生日悖论,你有 365 天,所以经验法则告诉你,有 365^.5 或大约 19 个人,你已经有相当大的碰撞机会(>50% 的正确答案:23人们)。

    在这里,有 13,983,816 种可能的结果,经验法则告诉您,在 3739 次平局中,您很有可能发生冲突(50% 的正确答案:4400 次平局)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-03
      • 2014-03-11
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多