为了账号安全,请及时绑定邮箱和手机立即绑定

随机数生成器过于频繁地重复某些数字

随机数生成器过于频繁地重复某些数字

Go
慕妹3146593 2021-12-07 17:06:50
我正在编写一个彩票开奖模拟程序作为一个项目。游戏的运作方式是您需要从 49 中选出 6 个号码才能获胜。您获胜的机会是 1/13,983,816,因为这是 49 种组合中有 6 种组合。将demo program on Go playground产生围绕循环下去,每次六个新的号码。每次生成一组新数字时,我都会测试它是否已经存在,如果存在,我会跳出循环。对于 13,983,816 种组合,您会认为需要很长时间才能重复相同的 6 个数字,但是在测试中它总是在 10000 次迭代之前失败。有谁知道为什么会这样?
查看完整描述

3 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

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

  1. 您使用 Go 游乐场,在那里您的随机性是固定的。这条线rand.Seed(time.Now().UnixNano())总是产生相同的种子,因为time.Now()是相同的。

  2. 你用你的模拟测试完全不同的东西。我会在最后写下它。

  3. 如果你想做一些类似于赌博的事情——你必须使用加密安全的 PRNG并且Go 拥有它。如果您愿意,可以在此处阅读更多详细信息(答案是 php 问题,但它解释了区别)。


在概率部分:

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

但是你要做的是检查碰撞的概率。有 N 个人,他们中的一些人会选择相同的集合(甚至不一定是获胜的集合)。这就是著名的生日悖论。正如你在那里看到的,碰撞的概率随着人数 N 的增加而急剧增加。

这绝对是相同的问题,但是您一年中的天数是13,983,816,您可以在此处检查,对于这个天数,您只需要 5000 次迭代即可保证 0.59% 会发生碰撞。通过 9000 次迭代,您会发现碰撞概率为 0.94。


查看完整回答
反对 回复 2021-12-07
?
隔江千里

TA贡献1906条经验 获得超10个赞

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



查看完整回答
反对 回复 2021-12-07
?
精慕HU

TA贡献1845条经验 获得超8个赞

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

所以,对于最初的生日悖论,你有 365 天,所以经验法则告诉你,如果有 365^.5 或大约 19 个人,你就有可能发生碰撞(>50% 的正确答案:23 个人)。

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


查看完整回答
反对 回复 2021-12-07
  • 3 回答
  • 0 关注
  • 217 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信