c++ - 关于调用 srand 的说明
问题描述
我想知道为什么在程序开始时播种 srand 是有利的,而不是在我使用它的地方。
我在程序开始时播种 srand 时生成伪随机数,但是当我在调用生成数字的函数中播种 srand 时,我得到的数字都是一样的
#include <iostream>
#include <ctime>
using namespace std;
int rng()
{
const int SIZE = 10;
int rng[10];
srand(time(NULL));
for (int i = 0; i < 10; i++)
{
rng[i] = rand() % 128 + 1;
return rng[i];
}
}
int main()
{
int array;
//srand(time(NULL)); If i put it here i get actual random numbers
cout << "Welcome to the program";
cout << "\nthis is your rng\n";
for (int i = 0; i < 10; i++)
{
array = rng();
cout << array << endl;
}
return 0;
}
当我运行程序时,所有数字都是相同的,但是当我从 rng 函数中删除种子并取消注释主模块中的 srand 时,数字是伪随机的,这正是我想要的。我想知道为什么。我已经调查过了,听说我用时间播种 srand ,当我运行该函数时,循环迭代得如此之快,以至于所有的数字都是用相同的种子值生成的,所以它们都是一样的,但我想知道这和在 main 中有什么区别 srand(time(NULL)) 因为无论哪种方式,函数生成数字的速度都不会那么快,它们无论如何都会处于相同的种子值?由于输出不同,它看起来不是那样,但我很好奇,为什么?
解决方案
time
返回自 1.1.1970 以来的秒数,因此在一秒钟内重复调用它确实会返回相同的值。srand
只要它在所有rand
调用之前放在哪里并不重要,并且每个程序只应该调用一次,因为它是全局的并且显然会重置随机序列。因此,如果您只在需要的地方使用它,那么当代码的其他部分也需要它并srand
再次调用时,您就有可能会干扰您的rand
调用。根本没有必要调用它,但种子将始终相同。有一个选项来确定性地设置种子对调试很有好处。
也就是说,不要使用它,只是不要。
正如您所观察到time
的,它不是一个好的种子生成器,rand
甚至不是一个好的随机数生成器,当然不是floats
and x mod n
。使用<random>
图书馆。它std::random_device
可以生成真正的随机数 = 好种子。可悲的是,它不是必需的。std::mt19937
是首选 RNG,它与std::XX_YY_distribution
s 一起应该绰绰有余,但最极端的随机性需求除外。它也是线程安全的,因为您可以控制对生成器的访问以及它的使用方式。
推荐阅读
- javascript - 在 React Bootstrap Table 中渲染 axios 响应
- r - 对于每一行,按 desc 顺序排序前 5 个值并获得列名
- c# - Microsoft.Office.Interop.Word 与 Office 2010 与 Visual Studio 2015 的问题
- swift - 将图像上传到 Firebase 存储只会覆盖 SwiftUI/Swift 5 中的当前照片?
- javascript - 为什么单击扩展时立即执行从 popup.js 向 content.js 发送消息的功能?
- vba - 通过 VBA 在电子邮件中放置图像
- java - 在spring mvc中从ajax调用jasperreport时出现解析器错误
- git - 在集成到主之前测试依赖的 git 功能分支 - 处理预发布
- firebase - 我想在 get 函数中获取用户 ID
- pycharm - 关于 PyCharm 中的自动代码折叠注释块