随机化种子会产生更随机的数字吗?

时间:2011-06-22 12:14:58

标签: c++ prng

我有三个关于RNG的问题。

第一个是可用作种子的数据。我总是用时间,但必须有其他容易获得的种子。

c ++中有哪些容易获得的种子?

如果我根据从RNG出来的下一个值以随机间隔重新接种RNG并从问题1的答案中随机选择种子,那么这将创建一个难以预测的伪随机链,因此更随机?

最后,在c ++中获取范围内随机数的最佳方法是什么?我一直在使用模数运算符,但我希望能够在范围内均匀分布,而不是像人工智能决策那样偏向高或低。

4 个答案:

答案 0 :(得分:3)

  1. 这取决于您需要rand。对于很多用途,time是 完全足够。对于其他人则不那么我通常会读四个字节 来自Unix机器上的/dev/random,如果是,则恢复为time /dev/random不可用。一个更有效的解决方案是 使用更高分辨率的计时器,并在进程或类似的东西中哈希 机器ID。

  2. 除非您正在使用,否则重播可能不会有太大变化 像/dev/random这样的事情。大多数其他可用 价值是可以预测的。

  3. 如果RAND_MAX是范围的倍数,则模数可以正常工作。如果它 不是,唯一的解决方案是抛弃价值观:你总共有 RAND_MAX + 1值,您需要n。而且没有可能 映射将所有RAND_MAX + 1值映射到n并具有 每个n的输入数量相同。通常的解决方案是什么 像:

  4.     int limit = (RAND_MAX + 1) - (RAND_MAX + 1) % n;
        int result = rand();
        while ( result >= limit )
            result = rand();
        return result % n;
    

    (我想在这里你正在寻找范围内的结果 [0...n)。并且RAND_MAX + 1不会溢出。)

    最后,如果您担心随机值的质量,请 意识到rand()的许多实现都不是特别好。 您可能希望切换到其中一个增强随机生成器。

答案 1 :(得分:2)

你应该看看boost::random

请记住:

  • 为了安全性或随机过程,为什么需要随机数?
  • “更随机”是什么意思?
  • 如果您根据算法重新种植并且该算法比基础RNG更可预测,那么您的开始时间比您开始时更差。如果你的种子只是32位值,那么即使是一个真正随机的种子源也会让事情更糟更好!
  • 如果你需要从随机源“混入”额外的随机性,最好通过XOR来做到这一点:即保持一个真正随机数的小垫,并将它们循环异或进入你的RNG输出 - 而不是偶尔再播种,偶尔再生垫。这样,你就不会丢掉RNG宝贵的内部状态。或者,如果您可以访问RNG内部,请使用真实的随机源偶尔通过类似的机制旋转一些位。

我希望你可以简单地使用boost::mt19937,但这实际上取决于应用程序。

答案 2 :(得分:1)

RNG的一个容易获得的种子是任何时间函数。种子不需要是随机的,只要每次启动程序时它都有所不同,这就足够了。试图使伪随机数“更随机”是一种有点愚蠢的努力。如果需要这样,那么发电机就不值得用盐了 此外,除非定期播种真正的随机噪音,否则你不会使输出任何“更随机”,如果你定期播种真随机噪音,只有种子真正随机,其他值仍然是确定性的,并且总共具有与此生成器生成的任何其他序列相同的统计特性。

如果不接受偏斜分布,通常实现将数字置于非幂二范围内的实现看起来有点像:

range = high - low;

while((r = rand()) > range) {}

r += low;

模数和乘法/除法具有众所周知的偏斜和溢出问题。

但是,如果按照你说的那样进行人工智能决定,我敢说没有人会注意到一个结果是否比另一个结果高出1%。因此简单地使用模数可能已经足够好,具有确定性时间,并且很简单。另请注意,您始终可以选择适合模数的范围。

答案 3 :(得分:0)

对于大多数应用程序来说,时间已经足够了,如果您需要更好的随机数,那么您应该查看提供此类功能的特定库。

对于范围生成,以下内容不会扭曲结果:

int random = rand() * RANGE / RAND_MAX;