在概率论和统计学中,随机变量的生成是一个基础而重要的任务。本文将介绍一种高效的随机变量生成器,特别是针对正态分布和指数分布的随机变量。该算法由George Marsaglia和Wai Wan Tsang提出,并在他们的论文[1]中进行了详细描述。本文将对该算法进行概述,并展示如何使用直方图对生成的数据进行分析。
随机变量生成器的核心算法基于Ziggurat方法,这是一种用于生成具有给定递减密度的随机变量的新版本。该方法比原始版本更快、更简单,能够在400MHz的PC上每秒生成1500万个正态或指数变量。生成器使用两个表:整数ki和实数wi。在大多数情况下(99%),所需的x值可以通过以下步骤生成:生成一个32位随机整数j,并让i成为j的右8位形成的索引。如果j < ki,则返回x = j * wi。
为了展示生成器的效果,本文提供了一个直方图模板类THistogram。这个类可以用于可视化生成的随机变量的分布情况。
正态分布在概率论和统计学中占有重要地位,这主要是因为中心极限定理,这是连接这两个学科的基础定理之一。正态分布也被称为高斯分布,以纪念首次使用该分布的卡尔·弗里德里希·高斯。网络上有许多关于正态分布的教程和演示小工具,因此本文不会深入数学细节。有关此主题的优秀网站可以在“概率与统计虚拟实验室”中找到。
CRandomGenerator类提供了两种类型的随机变量:正态分布和指数分布。这些是通过两个静态函数RNOR和REXP计算的:
float var = CRandomGenerator::RNOR();
float var = CRandomGenerator::RNOR(fMean, fSdev);
float var = CRandomGenerator::REXP();
生成器需要用“种子”初始化。通常,使用当前时间作为种子。这在CRandomGenerator的默认构造函数中隐式完成,因此在应用程序线程中使用生成器之前,只需要构建一个CRandomGenerator对象。在CWinApp::InitInstance函数中这样做是一个好主意。
THistogram是一个模板化的直方图类。模板参数T是输入数据类型,可以是float或double;TOut是结果数据类型,可以是float或double,默认设置为double。直方图由以下特征定义:一个区域,由最小和最大谱值定义(见Get/SetMinSpectrum和Get/SetMaxSpectrum);一个步长(见GetStep)。
可以通过不同的方式向直方图提供数据:
vector vData;
// 计算数据
THistogram histo(101);
// 计算直方图,最小和最大值自动计算...
histo.Compute(vData, true /* 计算 min, max */);
更新直方图:
vector vData;
// 更新直方图
histo.Update(vData);
更新单个数据条目:
float fData;
// 更新直方图
histo.Update(fData);
计算数据集的统计特性:可以使用静态方法GetMoments计算数据集的矩(均值、标准差、方差等):
float fMean, fAdev, fSdev, fVar, fSkew, fKurt;
// 依次计算均值、绝对均值、标准差、方差、偏度和峰度
THistogram::GetMoments(vData, fAdev, fSdev, fVar, fSkew, fKurt);
此方法在演示中用于比较由CRandomGenerator生成的正态分布和理论概率密度函数。
使用GetHistogram获取直方图结果。通过调用GetNormalizedHistogram获取标准化直方图(使其面积为1)。可以使用GetLeftContainers和GetCenterContainers访问区域的坐标。生成图表的代码如下:
vector vDistribution(histo.GetNormalizedHistogram());
vector vLeftPositions(histo.GetLeftContainers());
CPGLLine2D* pLine;
...
pLine->SetDatas(vLeftPositions, vDistributions);
演示应用程序展示了正态分布和指数分布。红色曲线代表随机值的直方图,蓝色曲线代表理论概率密度函数。演示应用程序包含两个项目:HistogramDemo使用Plot Graphic Library进行可视化。这里还有一篇关于PGL的文章。需要GDI+二进制文件才能使演示应用程序工作!(gdiplus.dll)HistogramMatlab使用Matlab引擎进行可视化。需要安装Matlab才能使演示应用程序工作!请注意,源代码使用Doxygen语法进行了文档化。
[1] The Ziggurat Method for Generating Random Variables, George Marsaglia and Wai Wan Tsang, Journal of Statistical Software, Vol 05, Issue 08.
[2] The Numerical recipies in C, Chapter 14.
2002年11月26日:在CRandomGenerator中添加了理论分布,添加了直方图面积计算,修复了标准化直方图。
2002年9月13日:添加了使用Matlab的新演示项目。
2002年9月11日:修复了演示项目并添加了演示中的二进制文件。