我有三个关于RNG的问题。
第一个是可用作种子的数据。我总是用时间,但必须有其他容易获得的种子。
c ++中有哪些容易获得的种子?
如果我根据从RNG出来的下一个值以随机间隔重新接种RNG并从问题1的答案中随机选择种子,那么这将创建一个难以预测的伪随机链,因此更随机?
最后,在c ++中获取范围内随机数的最佳方法是什么?我一直在使用模数运算符,但我希望能够在范围内均匀分布,而不是像人工智能决策那样偏向高或低。
答案 0 :(得分:3)
这取决于您需要rand
。对于很多用途,time
是
完全足够。对于其他人则不那么我通常会读四个字节
来自Unix机器上的/dev/random
,如果是,则恢复为time
/dev/random
不可用。一个更有效的解决方案是
使用更高分辨率的计时器,并在进程或类似的东西中哈希
机器ID。
除非您正在使用,否则重播可能不会有太大变化
像/dev/random
这样的事情。大多数其他可用
价值是可以预测的。
如果RAND_MAX
是范围的倍数,则模数可以正常工作。如果它
不是,唯一的解决方案是抛弃价值观:你总共有
RAND_MAX + 1
值,您需要n
。而且没有可能
映射将所有RAND_MAX + 1
值映射到n
并具有
每个n
的输入数量相同。通常的解决方案是什么
像:
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
。
请记住:
我希望你可以简单地使用boost::mt19937
,但这实际上取决于应用程序。
答案 2 :(得分:1)
RNG的一个容易获得的种子是任何时间函数。种子不需要是随机的,只要每次启动程序时它都有所不同,这就足够了。试图使伪随机数“更随机”是一种有点愚蠢的努力。如果需要这样,那么发电机就不值得用盐了 此外,除非定期播种真正的随机噪音,否则你不会使输出任何“更随机”,如果你做定期播种真随机噪音,只有种子真正随机,其他值仍然是确定性的,并且总共具有与此生成器生成的任何其他序列相同的统计特性。
如果不接受偏斜分布,通常实现将数字置于非幂二范围内的实现看起来有点像:
range = high - low;
while((r = rand()) > range) {}
r += low;
模数和乘法/除法具有众所周知的偏斜和溢出问题。
但是,如果按照你说的那样进行人工智能决定,我敢说没有人会注意到一个结果是否比另一个结果高出1%。因此简单地使用模数可能已经足够好,具有确定性时间,并且很简单。另请注意,您始终可以选择适合模数的范围。
答案 3 :(得分:0)
对于大多数应用程序来说,时间已经足够了,如果您需要更好的随机数,那么您应该查看提供此类功能的特定库。
对于范围生成,以下内容不会扭曲结果:
int random = rand() * RANGE / RAND_MAX;