C++ 比较随机数生成器

比较随机数生成器

随机库提供了一系列随机数生成器,每种生成器都有不同的策略和属性。在本示例中,我们将通过创建一个输出直方图来比较这些不同的选项。

如何做……

在本示例中,我们将比较C++随机库提供的不同随机数生成器:

我们首先定义一些常量,为随机数生成器提供统一的参数:

constexpr size_t n_samples{ 1000 }; constexpr size_t n_partitions{ 10 }; constexpr size_t n_max{ 50 };

n_samples 是要检查的样本数,n_partitions 是要在其中显示样本的分区数,n_max 是直方图中条形的最大大小(由于四舍五入,这会有所不同)。

这些数字提供了引擎之间差异的合理显示。增加样本数与分区数的比率往往会平滑曲线,并掩盖引擎之间的差异。

这是收集随机数样本并显示直方图的函数:

template void histogram(const string_view& rng_name) { auto p_ratio = (double)RNG::max() / n_partitions; RNG rng{}; // 构造引擎对象 // 收集样本 vector v(n_partitions); for(size_t i{}; i < n_samples; ++i) { ++v[rng() / p_ratio]; } // 显示直方图 auto max_el = std::max_element(v.begin(), v.end()); auto v_ratio = *max_el / n_max; if(v_ratio < 1) v_ratio = 1; cout << format(“engine: {}\n”, rng_name); for(size_t i{}; i < n_partitions; ++i) { cout << format(“{:02}:{:*<{}}\n”, i + 1, , v[i] / v_ratio); } cout << \n; }

简而言之,这个函数在向量中存储收集的样本的直方图,然后在控制台上以一系列星号显示直方图。

我们在main()中调用histogram()函数,如下所示:

int main() { histogram(“random_device”); histogram(“default_random_engine”); // … 其他引擎的调用 … }

输出:

C++ 比较随机数生成器

显示了前两个随机数生成器的直方图输出截图。您的输出将会有所不同。

如果我们将n_samples的值提高到100,000,您将发现引擎之间的差异变得更加难以区分:

C++ 比较随机数生成器

图 8.2 – 显示了具有100,000个样本的输出的截图。

它是如何工作的……

每个随机数引擎都有一个函数对象接口,用于返回序列中的下一个随机数:

result_type operator()();

函数对象返回一个随机值,该值在min()和max()值之间均匀分布。所有随机数引擎都共享此接口。

histogram()函数通过模板中使用随机数引擎的类来利用这种统一性:

template

(RNG是随机数生成器的常见缩写。库文档将这些类称为引擎,这对我们的目的来说与RNG是同义词。)

我们使用RNG类实例化一个对象,并在向量中创建一个直方图:

RNG rng{}; vector v(n_partitions); for(size_t i{}; i < n_samples; ++i) { ++v[rng() / p_ratio]; }

这使得我们能够使用这种技术轻松比较各种随机数生成器的结果。

还有更多……

库中的每个随机数生成器都有不同的方法和特性。当您多次运行直方图时,您会注意到大多数引擎每次运行时都具有相同的分布。这是因为它们是确定性的——也就是说,它们每次都会生成相同的数字序列。std::random_device 在大多数系统上是非确定性的。如果您需要更多的变化,可以使用它来初始化其他引擎之一。使用当前日期和时间来初始化RNG也是很常见的做法。

std::default_random_engine 对于大多数目的来说都是一个合适的选择。

免责声明:文章内容来自互联网,本站仅提供信息存储空间服务,真实性请自行鉴别,本站不承担任何责任,如有侵权等情况,请与本站联系删除。
转载请注明出处:C++ 比较随机数生成器 https://www.bxbdf.com/a/181300.shtml

上一篇 2025-04-15 20:20:46
下一篇 2025-04-15 20:27:42

猜你喜欢

联系我们

在线咨询: QQ交谈

邮件:362039258#qq.com(把#换成@)

工作时间:周一至周五,10:30-16:30,节假日休息。