我正在编写一个彩票抽奖模拟程序作为一个项目。游戏的运作方式是您需要从 49 中选出 6 个号码来获胜。
您获胜的机会是 1/13,983,816,因为这就是 49 中 6 的组合数量。 demo program on Go playground 每次循环都会生成六个新数字。
每次生成一组新数字时,我都会测试它是否已经存在,如果存在,我就会跳出循环。对于 13,983,816 种组合,您可能会认为需要很长时间才能重复相同的 6 个数字,但在测试中它总是在 10000 次迭代之前失败。有谁知道为什么会这样?
最佳答案
在我看来,你在这里有几个问题。
- 你使用 Go playground,你的随机性是固定的。这行
rand.Seed(time.Now().UnixNano())
总是产生相同的种子,因为time.Now()
是相同的。 - 你用你的模拟测试完全不同的东西。我会写在最后。
- 如果你想做类似于赌博的事情 - 你必须使用 cryptographically secure PRNG和 Go 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。
关于arrays - 随机数生成器过于频繁地重复某些数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35120321/