一、旧式rand():
旧式的随机数发生器沿用C的Rand()函数,这个函数会产生区间在[0,RAND_MAX]的伪随机数,且随机数近似可以看做符合均匀分布。
rand()函数的一些问题:
- 很多程序需要不同范围的随机数;
- 一些应用需要随机浮点数;
- 一些程序需要非均匀分布的数;
而程序员为了解决这些问题而试图转换rand生成的随机数的范围、类型或分布时,常常会引入非随机性。
二、新标准引擎和分布:
C++ 11新标准针对这两点做了很大的改进——随机数发生器(定义在头文件random)。
新设施利用两部分来生成随机数:
(1)、random number engines(引擎类):负责生成原始随机数
(2)、random number distributions(分布类): 迫使生成的随机数在统计上满足指定的概率分布。
//引擎和分布类型都是函数对象,都重载了函数调用运算符
default_random_engine e; //默认随机数引擎
e.seed((unsigned int)time(0)); //设置引擎种子(不够好的种子)
for (int i = 0; i != 10; ++i)
{
cout << e() << " "; //生成原始随机数,往往没什么用
}
cout << endl; //3779844781 2768557194 1707861555 2353173864 1894018264 841293267 2185308307 4182713741 3917642299 3478155669
//分布类型以随机数引擎本身为参数,将引擎生成的随机数映射到指定分布
uniform_int_distribution<unsigned> u(0, 9); //均匀分布类型,指定范围0~9
for (int i = 0; i != 10; ++i)
{
cout << u(e) << " "; //生成0~9范围内的均匀分布的随机数
}
cout << endl; //7 4 4 2 2 5 0 1 7 1
/*C++11提供了一个非常友好的类:random_device。这个类的作用是,
可以产生non-deterministic random numbers.
这个类有可能产生真正的随机数,不过真是效果和具体实现有关。
显然我们可以利用random_device去初始化我们的随机数种子*/
random_device r;
e.seed(r());//重置种子
for (int i = 0; i != 10; ++i)
{
cout << u(e) << " ";
}
cout << endl;
三、引擎和分布列表(来自cplusplus.com):