根据C / C ++的正态分布生成随机数

问题描述 投票:113回答:18

如何按照C或C ++的正态分布轻松生成随机数?

我不希望使用Boost。

[我知道Knuth详尽地谈论了这个问题,但是我现在没有他的书。

c++ c random distribution normal-distribution
18个回答
91
投票

generate Gaussian-distributed numbers from a regular RNG有很多方法。

Box-Muller transform是常用的。它会正确产生具有正态分布的值。数学很简单。您生成两个(均匀)随机数,然后对它们应用公式,就得到两个正态分布的随机数。返回一个,并将另一个保存为下一个随机数请求。


46
投票

C ++ 11

C ++ 11提供了std::normal_distribution,这就是我今天要去的方式。

C或更旧的C ++

以下是按复杂度升序排列的一些解决方案:

  1. 将0到1之间的12个统一随机数相加并减去6。这将与正态变量的均值和标准差匹配。一个明显的缺点是范围限制为±6,这与真实的正态分布不同。

  2. Box-Muller变换。这已在上面列出,并且实现起来相对简单。但是,如果您需要非常精确的样本,请注意,将Box-Muller变换与某些均匀生成器结合使用会遇到一个称为Neave Effect 1] ..

    的异常现象。
  3. 为了获得最佳精度,我建议绘制制服并应用逆累积正态分布以得出正态分布变量。 std::normal_distribution是逆累积正态分布的很好算法。

  4. 1。 H. R. Neave,“将Box-Muller变换与乘法同余伪随机数生成器一起使用”,《应用统计》,22,92-97,1973


31
投票

一种快速简便的方法只是求和多个均匀分布的随机数并取其平均值。请参阅Here,以获取有关其工作原理的完整说明。


24
投票

我创建了一个Central Limit Theorem


14
投票

这是一个C ++示例,基于一些参考。这既快速又肮脏,最好不要重新发明并使用boost库。


12
投票

使用#include "math.h" // for RAND, and rand double sampleNormal() { double u = ((double) rand() / (RAND_MAX)) * 2 - 1; double v = ((double) rand() / (RAND_MAX)) * 2 - 1; double r = u * u + v * v; if (r == 0 || r > 1) return sampleNormal(); double c = sqrt(-2 * log(r) / r); return u * c; }


12
投票

这是在现代C ++编译器上生成示例的方式。


4
投票

您可以使用#include <random> ... std::mt19937 generator; double mean = 0.0; double stddev = 1.0; std::normal_distribution<double> normal(mean, stddev); cerr << "Normal: " << normal(generator) << endl; 。一些GSL来演示如何使用它。


4
投票

看一下:complete examples are given。这是产生正态分布的最简单方法。


4
投票

如果使用的是C ++ 11,则可以使用http://www.cplusplus.com/reference/random/normal_distribution/


3
投票

我遵循了std::normal_distribution中给出的PDF的定义,并提出了以下要求:


1
投票

comp.lang.c FAQ列表


1
投票

Box-Muller实现:


1
投票

存在多种用于逆累积正态分布的算法。在http://c-faq.com/lib/gaussian.html]上测试了最受欢迎的量化金融

我认为,除了#include <cstdlib> #include <cmath> #include <ctime> #include <iostream> using namespace std; // return a uniformly distributed random number double RandomGenerator() { return ( (double)(rand()) + 1. )/( (double)(RAND_MAX) + 1. ); } // return a normally distributed random number double normalRandom() { double y1=RandomGenerator(); double y2=RandomGenerator(); return cos(2*3.14*y2)*sqrt(-2.*log(y1)); } int main(){ double sigma = 82.; double Mi = 40.; for(int i=0;i<100;i++){ double x = normalRandom()*sigma+Mi; cout << " x = " << x << endl; } return 0; } 中的算法AS241外,没有太多动机去使用其他东西:机器精度高,可靠且快速。高斯随机数生成中很少出现瓶颈。


0
投票

1]可以使用类似于蒙特卡洛方法的方法直观地生成高斯随机数。您可以使用C中的伪随机数生成器在高斯曲线周围的框中生成一个随机点。您可以使用分布方程式来计算该点是在高斯分布的内部还是下方。如果该点在高斯分布内,那么您就获得了高斯随机数作为该点的x值。


0
投票

蒙特卡罗方法


-1
投票

看看我发现了什么。


-3
投票

计算机是确定性设备。计算中没有随机性。此外,CPU中的算术设备可以评估一些有限的整数集(在有限域中执行评估)和有限的实有理数集。并且还执行了按位运算。数学处理了很多更出色的集合,例如[0.0,1.0],并且具有无限的点数。

© www.soinside.com 2019 - 2024. All rights reserved.