迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C++ >

C++ 中的种子随机数生成器

作者:迹忆客 最近更新:2023/04/09 浏览次数:

C++ 等编程语言不会生成真正的随机数。相反,计算机使用数学函数生成伪随机数。

本文讨论了生成随机数中种子的概念以及为 C++ 中用于生成随机数的函数提供种子的方法。


C++ 中随机数生成器中种子的概念

C++ 使用确定性算法生成随机数序列。因此,数字序列是伪随机的,而不是纯粹的概率。

在这种情况下,种子充当算法的起点。你不应将其视为生成的第一个数字将是种子。

相反,该算法从种子定义的分布中随机选择数字。如果你为算法提供相同的种子,它将生成相同的伪随机数序列。

但是,大多数情况下,你可能需要为每次执行生成不同的伪随机数序列。在这种情况下,你需要在每次执行算法时为其提供不同的种子。


使用 srand() 函数在 C++ 中播种随机数生成器

srand() 函数接受无符号整数作为参数。它使用参数为生成伪随机数的算法播种。

语法:

void srand (unsigned int seed);

如果你提供 1 作为 srand() 函数的参数,它会将伪随机数生成器初始化为其初始值。生成器产生与上次调用 rand() 函数相同的结果。

让我们看一个示例,该示例使用从用户那里获取的任意数字作为输入来播种伪随机数生成器。

示例代码:

#include<iostream>

using namespace std;

int main()
{
    unsigned int seed;
    cout<<"Enter seed value:\n";
    cin>>seed;
    srand(seed);
    cout<<"Successfully seeded the generator\n";
    return 0;
}

输出:

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
Enter seed value:
12
Successfully seeded the generator

使用 time() 函数在 C++ 中播种随机数生成器

前一种方法的问题是用户可以多次输入相同的数字。如果你需要确保每次执行算法时都提供不同的种子,请使用 time() 函数为伪随机数生成器提供种子。

C++ 中的 time() 函数返回当前 UNIX 时间戳,即自 UTC 时间 1970 年 1 月 1 日 00:00 小时以来经过的秒数。

语法:

time_t time (time_t* timer);

该函数将参数作为 time_t 类型的指针。如果你提供对函数的非空引用作为参数,它会将 time_t 类型的对象设置为保存当前时间戳的参数。

time_t 类型是算术类型的别名,可以保存当前的 UNIX 时间戳值。它实际上是一个无符号整数值。

示例代码:

#include<iostream>

using namespace std;

int main()
{
    srand(time(NULL));
    cout<<"Successfully seeded the generator\n";
    return 0;
}

请注意,代码将 NULL 作为参数传递给 time() 函数。根据代码,出于任何原因,你不需要类型为 time_t 的对象。

输出:

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
Successfully seeded the generator

播种要避免的随机生成器错误

通常,你在代码的循环中生成一系列伪随机数。大多数人犯的一个常见错误是每次循环执行时都为生成器播种。

在这种情况下,你可能会得到重复的数字,因为每次你使用相同的数字播种时,生成器都会创建相同的数字序列。

即使你使用 time() 函数为随机生成器播种也是如此,因为 time() 函数返回自过去某个固定日期以来经过的秒数。

另一方面,循环将执行得更快,因此每次调用 time() 函数将保持返回相同的值,直到经过一秒。这样,你最终将向生成器播种相同的值。

示例代码:

#include<iostream>

using namespace std;

int main()
{
    for(int i=1;i<=10;i++)
    {
        srand(time(NULL));
        cout<<rand()<<" ";
    }
    cout<<endl;
    return 0;
}

输出:

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454

代码在循环内播种随机生成器,并且执行十次相同的结果。你应该始终在循环之前为随机数生成器播种以避免这种陷阱。

让我们看一下代码在循环外播种随机生成器的示例。

示例代码:

#include<iostream>

using namespace std;

int main()
{
    srand(time(NULL));
    for(int i=1;i<=10;i++)
    {
        cout<<rand()<<" ";
    }
    cout<<endl;
    return 0;
}

输出:

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
213462937 1076978976 1207347426 8310730 1551061902 266528745 944000672 871831053 1678325834 868781842

观察代码导致不同的数字序列。


结论

你可以将种子提供给充当算法起点的伪随机生成器,但你应该小心避免陷阱,如文章中所述。否则,可能会导致不需要的结果。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Arduino 中停止循环

发布时间:2024/03/13 浏览次数:444 分类:C++

可以使用 exit(0),无限循环和 Sleep_n0m1 库在 Arduino 中停止循环。

Arduino 复位

发布时间:2024/03/13 浏览次数:315 分类:C++

可以通过使用复位按钮,Softwarereset 库和 Adafruit SleepyDog 库来复位 Arduino。

Arduino 的字符转换为整型

发布时间:2024/03/13 浏览次数:181 分类:C++

可以使用简单的方法 toInt()函数和 Serial.parseInt()函数将 char 转换为 int。

Arduino 串口打印多个变量

发布时间:2024/03/13 浏览次数:381 分类:C++

可以使用 Serial.print()和 Serial.println()函数在串口监视器上显示变量值。

Arduino if 语句

发布时间:2024/03/13 浏览次数:123 分类:C++

可以使用 if 语句检查 Arduino 中的不同条件。

Arduino ICSP

发布时间:2024/03/13 浏览次数:214 分类:C++

ICSP 引脚用于两个 Arduino 之间的通信以及对 Arduino 引导加载程序进行编程。

使用 C++ 编程 Arduino

发布时间:2024/03/13 浏览次数:127 分类:C++

本教程将讨论使用 Arduino IDE 在 C++ 中对 Arduino 进行编程。

Arduino 中的子程序

发布时间:2024/03/13 浏览次数:168 分类:C++

可以通过在 Arduino 中声明函数来处理子程序。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便