【问题标题】:How do you make an algorithm for a Random Number Generator?你如何为随机数生成器制作算法?
【发布时间】:2013-05-17 15:19:46
【问题描述】:

根据我的一位老师的说法,为了做到这一点,您需要制作两个包含数位小数的数组。一正一负。

数组 1 [0] = 例如 1.5739

数组 2 [0] = 例如 -5.31729

然后你找到当前时间

201305220957 或 2013 年 5 月 22 日上午 9:57

并使用这个等式:

(201305211647*1.5739)--5.31729

-然后你使用绝对值并四舍五入到小数点后 1.0,你就有了你的数字

在大多数生成器中,值是否取决于时间?

【问题讨论】:

  • 返回的值取决于大多数生成器的种子值,种子可能与时间相关,也可能与用户认为合适的时间无关。
  • 有两个主要组成部分:一个接受一些输入并产生看似随机输出的函数(尽管在给定相同输入的情况下总是提供相同的结果),然后是一个种子,它是某种随机数据,您输入后一个函数。该函数(在计算机上)是一个伪随机生成器。种子可以从任何足够随机的来源中获取。当前时间是一个非常糟糕的候选。
  • 不是以这种明显的方式,但许多生成器是按系统中发生某些中断的时间或间隔播种的。启动几分钟后,它通常“无法预测”。
  • “在大多数生成器中,值是否取决于时间?”没有这里那么多。
  • 我的大脑刚刚超负荷运转……如果时间静止,RNG 会产生什么?如果时间静止,如果它不能在时间间隔内对外部源进行采样,那么“真正随机”的数字生成器能否发挥作用?

标签: algorithm random


【解决方案1】:

前面的底线 - 生成随机数真的很难做到正确,并且严重烧毁了一些非常聪明的人(John Von Neumann 之一)。普通人不应该尝试创建自己的 RNG 算法。它需要数论、概率和统计以及数值计算方面的专业知识。除非您在所有三个领域都符合资格,否则最好使用由具有资格的人开发的算法。如果您想知道如何正确操作,可以在 http://en.wikipedia.org/wiki/Random_number_generationhttp://en.wikipedia.org/wiki/Pseudorandom_number_generator 找到很多有用的信息。

说白了,你的老师对这个话题一窍不通。

【讨论】:

    【解决方案2】:

    如果您需要为加密或统计目的生成随机数 - 您需要一个经过充分研究的生成器。我喜欢的一个是 Mersenne Twister,它具有非常好的统计特性,运行速度快且易于编码。

    如果您只需要一个合理的随机生成器 - 例如让游戏中的事物看起来是随机的 - 您可以使用经典的“线性全等生成器”,它编写起来很简单,并且可以产生看起来非常随机的输出。 (对于重型计算不安全)。

    LCG 生成器:

    int seed = 0x333; // chose any number.
    
    int random() { seed = ( seed * 69069 ) + 1;  return seed; }
    

    您可以使用几个数字来代替 69069。但不要选择您自己的。如果您不喜欢 69069,请从此处选择一个。

    http://en.wikipedia.org/wiki/Linear_congruential_generator

    【讨论】:

    • 您忘记了 + 1 项...请注意,您发布的生成器的周期为 2^30,初始种子为 1,这不是很好,并且还有其他缺陷。如果您要发布 sn-p ,至少要正确复制算法:[
    • 很好的例子,说明正确使用 RNG 有多难。 1)正如@Thomas 指出的那样,您忽略了添加一个。 2)您依靠位溢出来隐式执行 % 操作 - 这不是可移植的。 3)乘法和模运算应该以长精度完成,与第 2 点相关。 4) LCG 的良好实现不需要奇数种子。 5) 不良的统计特性。基于“生日悖论”,我可以在 sqrt(M) 之后将模数 M 的 LCG 固定为非随机数,因为真正的独立随机数会有重复。在你完成完整周期之前,LCG 没有重复。
    • 仍然依赖位溢出。也许如果你不相信我,你会相信securecoding.cert.org/confluence/display/seccode/…
    【解决方案3】:

    维基百科有很多很棒的页面专门用于随机数生成 (RNG)。一页专门讨论listing 历史上使用的各种类型的随机数生成器。最早和最弱的方法之一被称为中方方法 - 易于在编程中实现并适用于许多低级任务。一些计算机在电路中内置了一个线性反馈移位寄存器 (LFSR),用于生成随机数,但它不是很先进。 Mersenne Twister 是一种更现代的生成器(不是最现代的),被认为是加密安全的(在不可预测的意义上)。

    正确地说,这些是伪随机数生成器 (PRNG),因为它们不是真正随机的。它们不是真正随机的,因为计算机是确定性机器(状态机);没有预先确定的算法可以通过编程来从已知的先前状态生成真正的随机数。

    也就是说,真随机数发生器 (TRNG) 硬件电路(通常是模拟)的发明确实存在,并且以不同的方式接近。从检查温度和压力等环境条件,到更细微和更受原子/量子条件影响的现象,例如带有反馈的多稳态电路处于什么状态。大多数现代个人计算机都没有使用它,如果他们这样做,可能只使用它来查找 PRNG 的种子值。然后,您还拥有通过 Internet 连接进行检查的 RNG 程序,以在线查找随机数服务器,其中大多数使用 TRNG。您甚至可以依赖已记录在案的真实世界现象中的查找表;查找表是非常古老的学校。

    伪随机数生成器仅具有随机性的外观,即它们遵循特定的分布,并且从先前的值预测未来值的能力并不容易。有一组diehard tests,其唯一目的是测试随机数生成器的质量。但总的来说,PRNG 是一种产生整数序列的算法。理想情况下,我们正在寻找一种算法,该算法可以从序列中的先前项中产生适当地不可预测的数字序列(这是最难的部分),同时还遵循特定的分布(通常是均匀的),这意味着a中的每个值范围是等比例产生的。

    一般来说,将一个发行版转换为另一个发行版是一项微不足道的任务,无论它是 TRNG 还是 PRNG。均匀离散整数分布(这是 PRNG 生成的)可以使用各种保持均匀性的缩放技术轻松扩展或压缩以跨越任意整数区间,或者通过随机选择一个大整数并对其进行缩放来转换为均匀浮点分布下降到一个浮动等。

    使用逆变换采样、拒绝采样或简单代数等多种方法,可以轻松地将均匀浮点数转换为任何其他非均匀分布,例如正态分布、卡方分布、指数分布等分布的关系(例如,卡方只是独立正态分布的平方和)。此外,一些分布可以使用应用于统一浮点数的简单数学函数适当地近似。

    最终,该主题中大多数研究的最难部分和核心在于生成那些均匀分布的整数,它们构成了所有其他分布的基础。

    例如,使用时钟时间来获取初始种子值并没有根本上的错误。但是,我倾向于使用以微秒表示的时间的低三位或四位有效数字,以用于适当的不可预测的事情。或者为了同样的目的在计算机中使用 LFSR,开始更高级的算法。

    【讨论】:

      猜你喜欢
      • 2012-01-05
      • 1970-01-01
      • 2016-01-16
      • 1970-01-01
      • 2020-03-09
      • 1970-01-01
      • 2013-07-20
      • 2010-12-15
      • 2010-09-24
      相关资源
      最近更新 更多