最近,我遇到了一种在C ++ 11中生成随机数的新方法,但是无法消化我所读到的论文(该引擎是什么,数学术语就像“ 分布”,“产生的所有整数均可能相等 ”)。
所以任何人都可以解释一下
- 这些是什么?
- 他们是什么意思?
- 怎么产生的?
- 他们如何工作?
- 等等
您可以在一个有关随机数生成的常见问题解答中将其全部调用。
最近,我遇到了一种在C ++ 11中生成随机数的新方法,但是无法消化我所读到的论文(该引擎是什么,数学术语就像“ 分布”,“产生的所有整数均可能相等 ”)。
所以任何人都可以解释一下
您可以在一个有关随机数生成的常见问题解答中将其全部调用。
Answers:
这个问题太宽泛,无法给出完整的答案,但让我挑几个有趣的观点:
假设您有一个简单的随机数生成器,它以相等的概率生成数字0、1,...,10(将其视为经典rand()
)。现在,您需要0、1、2范围内的随机数,每个概率均等。你的下意识反应是采取rand() % 3
。但是,等等,余数0和1比余数2更频繁地出现,所以这是不正确的!
这就是为什么我们需要适当的分布,它需要一个均匀的随机整数源,并将它们变成我们想要的分布,如Uniform[0,2]
示例中所示。最好把它留给一个好的图书馆!
因此,所有随机性的核心是一个好的伪随机数生成器,该生成器生成一个在一定间隔内均匀分布的数字序列,理想情况下,其周期很长。标准的实现rand()
通常不是最好的,因此最好有一个选择。线性同余和Mersenne捻线机是两个不错的选择(LG实际上也经常被LG使用rand()
)。再次,最好让库来处理。
简单:首先,设置一个引擎并将其播种。种子完全确定“随机”数的整个序列,因此a)/dev/urandom
每次使用不同的数字(例如,取自),并且b)如果希望重新创建随机选择序列,则存储种子。
#include <random>
typedef std::mt19937 MyRNG; // the Mersenne Twister with a popular choice of parameters
uint32_t seed_val; // populate somehow
MyRNG rng; // e.g. keep one global instance (per thread)
void initialize()
{
rng.seed(seed_val);
}
现在我们可以创建发行版:
std::uniform_int_distribution<uint32_t> uint_dist; // by default range [0, MAX]
std::uniform_int_distribution<uint32_t> uint_dist10(0,10); // range [0,10]
std::normal_distribution<double> normal_dist(mean, stddeviation); // N(mean, stddeviation)
...并使用引擎创建随机数!
while (true)
{
std::cout << uint_dist(rng) << " "
<< uint_dist10(rng) << " "
<< normal_dist(rng) << std::endl;
}
<random>
与传统rand()
方法相比,更重要的一个原因是,现在很清楚并且很明显如何使随机数生成线程安全:为每个线程提供自己的,线程本地的引擎,以线程本地的种子为种子或同步访问到引擎对象。
std::random_device
值得一提,而不是/dev/urandom
随机数生成器是一个方程,给定一个数字,将为您提供一个新数字。通常,您要么提供第一个数字,要么从系统时间之类的东西中提取它。
每次您要求一个新数字时,它都会使用先前的数字执行方程式。
如果随机数生成器倾向于产生比其他数字更多的相同数字,则认为它不是很好。也就是说,如果您想要一个介于1到5之间的随机数,并且您具有以下这种数字分布:
2比任何其他数字生成FAR的频率更高,因此比其他数字更可能生成FAR。如果所有数字都一样,您将有20%的机会每次获得每个数字。换句话说,由于赞成2,所以上述分布非常不均匀。所有20%的分布都是偶数。
通常,如果您想要一个真正的随机数,则可以从天气或其他自然资源中获取数据,而不是从随机数生成器中获取数据。
rand
,您应该快速了解Wikipedia的一些基本统计信息和RNG概念,否则,将很难向您解释<random>
其各个部分的原理和用法。