C++ Boost Random随机函数详解
无水先生 人气:0一、说明
Boost.Random 库提供了许多随机数生成器,可让您决定应如何生成随机数。在 C++ 中,始终可以使用来自 cstdlib 的 std::rand() 生成随机数。但是,使用 std::rand() 生成随机数的方式取决于标准库的实现方式。
当包含头文件 boost/random.hpp 时,您可以使用 Boost.Random 中的所有随机数生成器和其他类和函数。
该库的大部分已添加到 C++11 的标准库中。如果您的开发环境支持 C++11,您可以通过包含头文件 random 并访问命名空间 std 来重写本章中的 Boost.Random 示例。
二、示例代码
示例 60.1。带有 boost::random::mt19937 的伪随机数
#include <boost/random.hpp> #include <iostream> #include <ctime> #include <cstdint> int main() { std::time_t now = std::time(0); boost::random::mt19937 gen{static_cast<std::uint32_t>(now)}; std::cout << gen() << '\n'; }
示例 60.1 访问随机数生成器 boost::random::mt19937。运算符 operator() 生成一个随机数,并将其写入标准输出。
boost::random::mt19937 生成的随机数是整数。生成整数还是浮点数取决于您使用的特定生成器。所有随机数生成器都定义类型 result_type 以确定随机数的类型。 boost::random::mt19937 的 result_type 是 boost::uint32_t。
所有随机数生成器都提供两个成员函数:min() 和 max()。这些函数返回该随机数生成器可以生成的最小和最大数字。
Boost.Random 提供的几乎所有随机数生成器都是伪随机数生成器。伪随机数生成器不会生成真正的随机数。它们基于生成看似随机数的算法。 boost::random::mt19937 是这些伪随机数生成器之一。
伪随机数生成器通常必须进行初始化。如果它们用相同的值初始化,它们将返回相同的随机数。这就是为什么在示例 60.1 中,std::time() 的返回值被传递给 boost::random::mt19937 的构造函数。这应该保证当程序在不同的时间运行时,会产生不同的随机数。
伪随机数对于大多数用例来说已经足够好了。 std::rand() 也基于伪随机数生成器,它必须用 std::srand() 初始化。不过Boost.Random提供了一个随机数生成器,可以生成真正的随机数,只要操作系统有生成真正随机数的源即可。
示例 60.2。带有 boost::random::random_device 的实随机数
#include <boost/random/random_device.hpp> #include <iostream> int main() { boost::random::random_device gen; std::cout << gen() << '\n'; }
boost::random::random_device is a non-deterministic random number generator,这是一个随机数生成器,可以产生真正的随机数。没有需要初始化的算法。因此,预测随机数是不可能的。非确定性随机数生成器通常用于与安全相关的应用程序。
boost::random::random_device 调用操作系统函数来生成随机数。如果像示例 60.2 一样调用默认构造函数,则 boost::random::random_device 在 Windows 上使用加密服务提供程序 MS_DEF_PROV,在 Linux 上使用 /dev/urandom 作为源。
如果您想使用其他来源,请调用 boost::random::random_device 的构造函数,它需要一个 std::string 类型的参数。如何解释此参数取决于操作系统。在 Windows 上,它必须是加密服务提供商的名称,在 Linux 上,它必须是设备的路径。
请注意,如果您想使用 boost::random::random_device 类,则必须包含 boost/random/random_device.hpp。 boost/random.hpp 不提供此类。
示例 60.3。具有 bernoulli_distribution 的随机数 0 和 1
#include <boost/random.hpp> #include <iostream> #include <ctime> #include <cstdint> int main() { std::time_t now = std::time(0); boost::random::mt19937 gen{static_cast<std::uint32_t>(now)}; boost::random::bernoulli_distribution<> dist; std::cout << dist(gen) << '\n'; }
示例 60.3 使用伪随机数生成器 boost::random::mt19937。此外,还使用了分布。分布是 Boost.Random 类,它将随机数范围从随机数生成器映射到另一个范围。虽然像 boost::random::mt19937 这样的随机数生成器具有内置的随机数下限和上限,可以使用 min() 和 max() 查看,但您可能需要不同范围内的随机数。
示例 60.3 模拟投掷硬币。因为硬币只有两个面,随机数生成器应该返回 0 或 1。boost::random::bernoulli_distribution 是一个返回两个可能结果之一的分布。
分布的使用类似于随机数生成器:您调用运算符 operator() 来接收随机数。但是,您必须将随机数生成器作为参数传递给分布。在示例 60.3 中,dist 使用随机数生成器 gen 返回 0 或 1。
示例 60.4。 1 到 100 之间的随机数,具有 uniform_int_distribution
#include <boost/random.hpp> #include <iostream> #include <ctime> #include <cstdint> int main() { std::time_t now = std::time(0); boost::random::mt19937 gen{static_cast<std::uint32_t>(now)}; boost::random::uniform_int_distribution<> dist{1, 100}; std::cout << dist(gen) << '\n'; }
Boost.Random 提供了多种分布。示例 60.4 使用了经常需要的分布:boost::random::uniform_int_distribution。此分布可让您定义所需的随机数范围。在示例 60.4 中,dist 返回 1 到 100 之间的一个数字。
请注意,dist 可以返回值 1 和 100。分布的下限和上限都包括在内。
除了 boost::random::bernoulli_distribution 和 boost::random::uniform_int_distribution 之外,Boost.Random 中还有许多分布。例如,boost::random::normal_distribution 和 boost::random::chi_squared_distribution 等分布用于统计。
加载全部内容