【问题标题】:Fast random normal distribution generator [closed]快速随机正态分布生成器 [关闭]
【发布时间】:2014-07-26 13:48:51
【问题描述】:

我目前正在扩展一个严重依赖随机正态分布数的模拟模型。目前它使用std::normal_distribution,但它太慢了。

有没有办法实现快速随机正态分布?只要遵循正态分布,这些值就不必是唯一的。

【问题讨论】:

  • 您很可能不会显着超越您的标准库供应商。唯一性与正态分布相矛盾。
  • std::normal_distribution 是一个发行版,而不是一个生成器。您将哪个生成器和哪个编译标志用于哪个代码?当然,如果数字的质量不是那么重要,您可以回退到非常简单的算法,例如使用r=++i%6
  • @BaummitAugen 你说得对,唯一性与正态分布相矛盾。当我说这句话时,我的意思是,0.5556 或 0.5559 对我来说并不重要,如果它有助于计算,我可以承受失去一些精度。
  • @phresnel 我使用 mt19937 (mersenne twister) 作为生成器,使用 -O3 -std=c++11 作为编译标志。回退到另一个生成器并不是一个真正的选择,我从其他人那里继承了模型,我不想开始使用模型参数。
  • 我想到的一个可能的解决方案是预先计算 10,000 个点并将它们存储在一个查找表中。然后在必要时从查找表中随机选择。

标签: c++ random normal-distribution


【解决方案1】:

Ziggurat generator by Marsaglia and Tsang (JSS, 2000) 被认为在统计上既可靠又快速。但是,您确实想要修改后的 Ziggurat 普通生成器,它根据 Leong et al (JSS, 2005) 的评论使用更好的底层统一生成器。

我有原始论文以及一些评论论文in this GitHub directory,这是 R 的 Ziggurat C++ 实现的一部分。

【讨论】:

【解决方案2】:

std::normal_distribution 是一个发行版,而不是一个生成器。您可能想尝试标准库中的其他生成器,看看哪种生成器最快(请参阅http://en.cppreference.com/w/cpp/numeric/random)。

如果数字的质量不是那么重要,您可以回退到非常简单的算法,例如使用r=++i%6

Linear congruential generator 也很容易实现(实际上,大多数标准的rand() 实现都使用其中的一些实现。但是,它可能不会比使用std::linear_congruential_engine 快。在上面的链接站点上也有一个数字易于“配置”的随机数生成器。

还有一个已故的 Marsaglia 的算法,可以在 here 找到,它非常有效 w.r.t。性能和数量质量。

最后,确保在测试性能时使用正确的优化标志。

【讨论】:

    【解决方案3】:

    标准的<random> 库允许使用生成器和分布的组合生成随机数。你正在使用正态分布,你想要的是一个比默认更快的生成器,看看here

    【讨论】:

    • 查看有关问题的 cmets。我们的答案是白费力气。
    猜你喜欢
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 2010-12-11
    • 2021-08-16
    • 2020-11-25
    • 2014-11-06
    相关资源
    最近更新 更多