C++中的伪随机数
2022-11-13 12:11:58
随机数
真随机数
自然界中的有很多不确定的物理现象,通过测量这些现象,就可以获得真随机数。
比如白噪声的幅值、电子元器件的电压噪声等,真随机数可以通过用硬件对这些参数进行采集获得。
伪随机数
伪随机数序列是用确定性的算法计算出来的周期很长的序列。
程序的运行过程是一个确定的过程,每一条指令都是确定的,因此不能产生真的随机数。
说到伪随机数就会说到种子,什么是种子呢,我们可以将种子理解为一个初始值,特定算法根据这个初始值产生一个一定的序列,生成的这个序列“看起来”是随机的,实际上是一个周期很长的确定序列。
如果每次的种子设置得相同,那么产生的序列都是相同的。
举个例子
我们可以简单的设置这个种子为某个数,比如1。
请看如下代码,用srand()设置种子的值,用rand()产生伪随机数序列,需要包含头文件#include <stdlib.h>。重复运行下列代码,因为种子相同,所以每次输出的序列都是如图的序列"41 18467 6334 26500 …"。
srand(1); // 设置种子的值为1,如果不设置,默认种子为1
for (int i = 0; i < 10; ++i) {
cout << rand() << " "; // 输出10个伪随机数
}
如果每次种子设置得不同,那生成的序列也将不同。 如何获得不同的种子呢?
可以用C语言中的库函数 time_t time(time_t *seconds) 返回自1970-01-01 00:00:00 UTC 起经过的时间,以秒为单位。
这个函数的入参seconds也能保存结果,请看如下代码,输出的t和seconds的值是一样的。
time_t seconds;
time_t t=time(&seconds);
cout << t <<" "<< seconds <<endl; // t和seconds的值是一样的
那么,我们将当前的时间设置为种子,由于时间一直在变,种子就一直在变,每次就能生成不同的伪随机数序列。
time_t t=time(nullptr);
srand(t); // 设置种子的值为时间
for (int i = 0; i < 10; ++i) {
cout << rand() << " ";
}
C++代码示例
题目
将1-100的有序序列变成无序序列,要求每次运行的结果不同。
// 题目:将1-100的有序序列变成无序序列,要求每次运行的结果不同。
void fun(vector<int> &vec) {
time_t t = time(nullptr);
srand(t); // 设置种子的值为时间
rand();
for (int i = 0; i < 500; ++i) {
// 每次随机交换数组中的两位
swap(vec[rand() % 100], vec[rand() % 100]);
}
}
int main() {
vector<int> vec(100);
for (int i = 0; i < 100; ++i) {
vec[i] = i+1;
}
fun(vec);
for (auto it : vec) {
cout << it << " ";
}
cout << endl;
system("pause");
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
相关文章