一、前言
在看C++生成随机数之前,先来看一下如何C语言如何生成随机数
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int i = 0;
// 初始化种子为随机值
srand((unsigned int)time(0));
for (; i < 5; ++i)
{
// 产生一个1-50之间的数
int num = rand() % 50 + 1;
printf("%d ", num);
}
printf("\n");
return 0;
}
当我们想要生成随机浮点数时,通常需要rand() / MAX_RAND,但是随机整数的精度通常低于随机浮点数,有一些浮点数就永远不会生成了,一起来看一下C++是怎么做的。
二、随机数引擎操作
Engine e; | 默认构造函数,使用该引擎类默认的种子 |
Engine e(s); | 使用整型值 s 作为种子 |
s.send(s); | 使用整型值 s 重置种子的状态 |
e.min(); | 引擎可生成的最小值 |
e.max(); | 引擎可生成的最大值 |
Engine::result_type; | 此引擎生成 unsigned 整型类型 |
e.discard(u); | 将引擎推进 u 步,u 的类型为 unsigned long long |
三、生成整型随机数
1. 生成无符号数,注意包含 #include <random>
#include <iostream>
#include <random>
#include <vector>
using namespace std;
int main()
{
uniform_int_distribution<unsigned> u(0, 9);
default_random_engine e;
for (int i = 0; i < 5; i++)
{
for (auto i = 0; i < 10; i++)
cout << u(e) << " ";
cout << endl;
}
return 0;
}
2. 生成一个 0~9 的随机数
#include <iostream>
#include <random>
using namespace std;
int main()
{
uniform_int_distribution<unsigned> u(0, 9);
default_random_engine e;
for (auto i = 0; i < 10; i++)
cout << u(e) << " ";
cout << endl;
return 0;
}
3. 将引擎和关联的对象修改为 static 的
#include <iostream>
#include <random>
using namespace std;
void Test()
{
uniform_int_distribution<unsigned> u(0, 9);
default_random_engine e;
for (auto i = 0; i < 10; i++)
cout << u(e) << " ";
cout << endl;
}
int main()
{
for (int i = 0; i < 5; i++)
{
Test();
}
return 0;
}
每次调用这个函数都将生成相同的随机数
为了解决这个错误,我们可以将引擎和关联的对象修改为 static 的
#include <iostream>
#include <random>
using namespace std;
void Test()
{
uniform_int_distribution<unsigned> u(0, 9);
default_random_engine e;
for (auto i = 0; i < 10; i++)
cout << u(e) << " ";
cout << endl;
}
int main()
{
for (int i = 0; i < 5; i++)
{
Test();
}
return 0;
}
可以看到生成了不同的随机数
4. 随机数种子
使用上面的函数每次调用都将生成相同的随机数,类似 C 语言,C++ 也有随机数种子
#include <iostream>
#include <random>
#include <time.h>
using namespace std;
int main()
{
uniform_int_distribution<unsigned> u(0, 9);
default_random_engine e;
e.seed(time(0));
cout << "e:";
for (auto i = 0; i < 10; i++)
cout << u(e) << " ";
cout << endl;
default_random_engine e1;
e1.seed(2356);
cout << "e1:";
for (auto i = 0; i < 10; i++)
cout << u(e1) << " ";
cout << endl;
e1.seed(2356);
cout << "e2:";
for (auto i = 0; i < 10; i++)
cout << u(e1) << " ";
cout << endl;
return 0;
}
相同的随机数种子生成的随机数是一样的
四、浮点型随机数生成
生成 0~1 的随机浮点数
#include <iostream>
#include <random>
using namespace std;
int main()
{
uniform_real_distribution<double> u(0, 1);
default_random_engine e;
for (auto i = 0; i < 10; i++)
cout << u(e) << " ";
cout << endl;
return 0;
}
默认为double,uniform_real_distribution<> u(0, 1) 相当于 uniform_real_distribution<double> u(0, 1);
0.814724 0.135477 0.905792 0.835009 0.126987 0.968868 0.913376 0.221034 0.632359 0.308167
五、非均匀随机数生成
1. 正态分布
#include <iostream>
#include <random>
#include <string>
#include <vector>
#include <time.h>
using namespace std;
int main()
{
default_random_engine e;
e.seed(time(0));
// 均值 4,标准差 1.5
normal_distribution<> n(4, 1.5);
std::vector<unsigned> array(9);
for (auto i = 0; i < 300; i++)
{
unsigned num = lround(n(e));
if (num < array.size())
++array[num];
}
for (auto i = 0; i != array.size(); i++)
cout << i << ":" << string(array[i], '*') << endl;
cout << endl;
return 0;
}
2. 生成一个 bool 值
#include <iostream>
#include <random>
#include <time.h>
using namespace std;
int main()
{
default_random_engine e;
e.seed(time(0));
bernoulli_distribution b;
for (auto i = 0; i < 20; i++)
{
cout << boolalpha << b(e) << " ";
}
cout << noboolalpha << endl;
return 0;
}
cout << noboolalpha << true; 将bool 值打印为 true 或者 false,而不是 0 和 1,cout << noboolalpha << endl; 取消
false true false false true false false true false true true false true true false false false false false false
58/52 的机会为 true
bernoulli_distribution b(.58);