重塑轮子:随机数发生器

时间:2011-05-01 21:28:01

标签: c++ algorithm random numbers seed

所以我是C ++的新手,我正在尝试学习一些东西。因此,我试图制作一个随机数发生器(如果你愿意,可以使用RNG或PRNG)。我有RNG的基本知识,就像你必须从种子开始,然后通过算法发送种子。我坚持的是人们如何提出所述算法。

以下是我必须获得种子的代码。

int getSeed()
{
    time_t randSeed;
    randSeed = time(NULL);
    return randSeed;
}

现在我知道C ++中有预构建的RNG,但我希望学习的不仅仅是复制其他人的工作并尝试解决它。​​

因此,如果有人能带我到我能阅读的地方或向我展示如何为此提出算法的例子,我将非常感激。

4 个答案:

答案 0 :(得分:5)

首先,只是为了澄清,你提出的任何算法都将是一个伪随机数发生器,而不是一个真正的随机数发生器。由于您将制作算法(即编写函数,即制作一组规则),随机数生成器必须最终重复自身或执行类似的非随机算法。

真正随机数生成器的示例是从自然中捕获随机噪声并将其数字化的实例。其中包括:

http://www.fourmilab.ch/hotbits/

http://www.random.org/

您还可以购买产生白噪声的物理设备(或其他随机方式)并以数字方式捕获它:

http://www.lavarnd.org/

http://www.idquantique.com/true-random-number-generator/products-overview.html

http://www.araneus.fi/products-alea-eng.html

就伪随机数生成器而言,最容易学习的(以及普通人可能自己制作的那些)是linear congruential generators。不幸的是,这些也是一些最糟糕的PRNG。

确定什么是优质PRNG的一些指导原则包括:

  1. 周期性(可用数字的范围是多少?)
  2. 连续数字(相同数字连续两次重复的概率是多少)
  3. 均匀性(是否可能从某个子范围中选择数字作为另一个子范围)
  4. 逆向工程难度很大(如果它接近真正随机,那么有人就不应该根据它生成的最后几个数字找出它生成的下一个数字)
  5. 速度(我可以多快生成一个新数字?需要5或500次算术运算)
  6. 我确定还有其他我不在想的
  7. 目前在大多数应用程序(即非密码学)中被认为是好的一个更受欢迎的是Mersenne Twister。正如您从链接中看到的,它是一个简单的算法,可能只有30行代码。然而,试图从头开始提出这些20或30行代码需要大量的智力和PRNG的研究。通常最着名的算法是由教授或行业专业人士设计的,他们已经研究过几十年的PRNG。

    我希望你研究PRNG并尝试自己动手(尝试Knuth的计算机程序设计或数字食谱作为起点),但我只想在一天结束时将这一切都打包出来(除非PRNGs只会使用别人想出的东西,这将是你生活中的工作。另外,按照这些思路,我想指出历史编译器,电子表格等不使用大多数数学家认为好的PRNG,所以如果你需要高质量的PRNG,请不要使用标准库在C ++,Excel,.NET,Java等等,直到你研究他们用它来实现它。

答案 1 :(得分:3)

通常使用线性同余生成器,Wiki article很好地解释了它。

答案 2 :(得分:3)

引用John von Neumann:

  

任何考虑算术的人   产生随机数字的方法是   当然是处于罪恶状态。

这取自Knuth的书“计算机程序设计的艺术”中的第3章随机数,该书必须是对该主题的最详尽的概述。一旦你读完它,你就会筋疲力尽。您还将知道为什么不想编写自己的随机数生成器。

答案 3 :(得分:0)

正确的解决方案最符合要求,每种情况的要求都是独一无二的。这可能是最简单的方法:

  • 创建一个大的一维数组 填充“真实”随机值。
  • “种子”你的伪随机生成器 用...计算起始指数 系统时间。
  • 遍历数组并返回 每个电话的价值 功能
  • 到达终点时缠绕。