C++11--随机数引擎和随机数分布

时间:2023-03-08 19:14:12
/* 随机数引擎:
* 有状态的随机数发生器,生成在预定义的最大小值之间的随机数
* 不是真正的随机数--伪随机
*/
int main ()
{
std::default_random_engine eng;
cout << "Min: " << eng.min() << endl;
cout << "Max: " << eng.max() << endl; cout << eng() << endl; // 生成一个随机数
cout << eng() << endl; // 生成第二个随机数 std::stringstream state;
state << eng; // 保存引擎状态 cout << eng() << endl; // 生成一个随机数
cout << eng() << endl; // 生成第二个随机数 state >> eng; // 恢复引擎状态
cout << eng() << endl; // 生成一个随机数,跟前面的值一模一样
cout << eng() << endl; // 生成第二个随机数,跟前面的值一模一样
} /* 更多例子 */
void printRandom(std::default_random_engine e) {
for (int i=0; i<10; i++)
cout << e() << " ";
cout << endl;
} template <typename T>
void printArray(T arr) {
for (auto v:arr) {
cout << v << " ";
}
cout << endl;
} int main ()
{
std::default_random_engine eng;
printRandom(eng); std::default_random_engine eng2;
printRandom(eng2); //值跟前面完全一样,所以引入种子 unsigned seed = std::chrono::steady_clock::now().time_since_epoch().count();
std::default_random_engine e3(seed); //
printRandom(e3); eng.seed(); // 重置引擎为初始状态
eng.seed(109); // 依据种子109设置引擎状态 eng2.seed(109);
if (eng == eng2) // 两个引擎状态相同就相同
cout << "eng and eng2 have the same state" << endl; cout << "\n\n Shuffling:" << endl;
int arr[] = {1,2,3,4,5,6,7,8,9};
vector<int> d(arr, arr+9);
printArray(d); vector<int> d = {1,2,3,4,5,6,7,8,9};
std::shuffle(d.begin(), d.end(), std::default_random_engine());
printArray(d);
std::shuffle(d.begin(), d.end(), std::default_random_engine()); // 相同顺序
printArray(d); std::shuffle(d.begin(), d.end(), eng);
printArray(d);
std::shuffle(d.begin(), d.end(), eng); // 不同顺序
printArray(d);
} /* 其他随机数引擎 参看cplusplus.com*/ /* 随机数分布 */
// 默认的引擎都是均匀分布,且取值范围固定 int main () {
// 引擎只是提供了一个随机源
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine e(seed);
// 如何获取一个0到5之间的随机数?
// e()%6
// -- 随机性差
// -- 只能均匀分布 std::uniform_int_distribution<int> distr(0,5); // range: [0,5] -- 0和5都包含,这个唯一一个全闭区间的特例
// 默认参数: [0, INT_MAX]
cout << " int_distribution: " << endl;
for (int i=0; i<30; i++) {
cout << distr(e) << " ";
} cout << "\n\n real_distribution: " << endl; std::uniform_real_distribution<double> distrReal(0,5); // 半开区间: [1, 5)
// default param: [0, 1)
for (int i=0; i<30; i++) {
cout << distrReal(e) << " ";
} cout << " poisson_distribution: " << endl;
std::poisson_distribution<int> distrP(1.0); // mean (double)
for (int i=0; i<30; i++) {
cout << distrP(e) << " ";
}
cout << endl; cout << " normal_distribution: " << endl;
std::normal_distribution<double> distrN(10.0, 3.0); // 平均值和标准差
vector<int> v(20);
for (int i=0; i<800; i++) {
int num = distrN(e); // convert double to int
if (num >= 0 && num < 20)
v[num]++; // v[num] 记录数字num出现的次数
}
for (int i=0; i<20; i++) {
cout << i << ": " << std::string(v[i], '*') << endl;
}
cout << endl; // Stop using rand()%n;
} /* 其他分布参看cplusplus.com*/