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");
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。 

相关文章