【问题标题】:non-repeating random numbers非重复随机数
【发布时间】:2013-08-11 10:09:16
【问题描述】:

我需要生成大约 9 到 1 亿个不重复的随机数,范围从零到生成的数字量,并且我需要非常快速地生成它们。对类似问题的几个答案提出了简单地对数组进行洗牌以获得随机数,而其他人则提出了使用布隆过滤器。问题是,哪个效率更高,如果是布隆过滤器,我该如何使用呢?

【问题讨论】:

  • 没有实际数字就无法回答这个问题。你需要多少个随机数,什么类型,什么范围,还有哪些你没有提到的约束? “真的很大”是没有意义的。你的意思是比记忆中的更多吗?
  • 我需要大约 9-1 亿个随机数,从零到生成的数字量不等,这意味着内存不是一个很大的问题,但我确实需要一个高效的算法,而且我是正如 ROOt_R3z 建议的那样,不确定存储生成的数字然后检查它们是否已经存在于存储中会花费多少时间。谢谢你的评论
  • 它们需要有多随机?安全是一个问题吗?

标签: random shuffle bloom-filter non-repetitive


【解决方案1】:

您根本不想要随机数。您想要的正是数字 0 到 N-1,以随机顺序排列。

简单地填充数组和洗牌应该很快。适当的 Fisher-Yates shuffle 是 O(n),因此在 C 甚至 Java 中,1 亿个数组应该花费不到一秒的时间,在 Python 等高级语言中稍慢。

您只需要生成 N-1 个随机数来进行 shuffle(如果您使用拒绝采样来获得完美的均匀性,则可能高达 1.3N),因此速度很大程度上取决于您的 RNG 的速度。

您永远不需要查看是否已经生成了一个数字;无论您使用哪种算法,这都会非常缓慢,尤其是在运行结束时。

如果您需要的总数略少于 N,请将数组从 0 填充到 N-1,然后尽早中止 shuffle 并获取部分结果。只有当您需要的数字数量与其范围相比非常小时,您才应该考虑生成并检查重复数据的方法。在那种情况下,Bob Floyd 的算法可能会很好。

【讨论】:

    【解决方案2】:

    作为替代方案,您可以使用适当大小的块密码。使用块密码对数字 0、1、2、...进行加密,您将得到一系列不重复的随机数。确切的系列将取决于您使用的密钥。它们保证不会重复,因为块密码是可逆排列。

    对于 64 位数字,使用 DES,对于 32 位数字,使用 Hasty Pudding(允许大范围的块大小)或编写您自己的简单 Feistel cypher。假设安全性不是一个大问题,那么自己编写是可能的。

    【讨论】:

      【解决方案3】:

      为了确保更好地创建一个算法来打乱数字,如果你使用种子,例如服务器微时间或时间戳,你可以为每毫秒有一个不同的随机字符串。

      使用 range 函数开始创建数组,根据需要设置数字的数量。 比,你需要使用种子来使伪随机性更好。 所以,你必须使用 SHUFFLE 而不是 rand, 因此,您将数组的范围设置为 1 到 90,设置种子,而不是使用 shuffle 对数组进行随机播放。比您以随机顺序获得所有数字(对应于种子)。 你必须改变种子才能有另一个结果。 数字的顺序就是结果。 如 .. 球 1 : 42 ... 球 2: 10.... 球 3: 50.... 球 1 在数组中为 0。 ;) 您还可以使用切片函数并创建一个 for / each 循环,增加切片因子,以便循环

      1. 切片数组 0,1 结果 .. 球 1...
      2. slice array 0.2 ball 2...
      3. 切片数组0.3

      这就是逻辑,我希望你明白,如果是这样..它会帮助你很多。

      【讨论】:

        猜你喜欢
        • 2013-12-24
        • 1970-01-01
        • 2011-11-24
        • 2012-01-20
        • 2011-07-19
        • 2013-04-06
        • 2017-10-25
        相关资源
        最近更新 更多