65.9K
CodeProject 正在变化。 阅读更多。
Home

一个正态/指数随机数生成器和直方图类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.73/5 (9投票s)

2002年9月9日

4分钟阅读

viewsIcon

280855

downloadIcon

8188

一个具有正态或指数分布的快速随机生成器 + 一个直方图类

Sample Image - zigurat.png

引言

随机变量生成器

本文介绍了一个用于生成随机变量(即正态分布和指数分布)的快速生成器。该算法出自 George Marsaglia 和 Wai Wan Tsang 在 [1] 中的工作。以下是他们论文的摘要:

我们提供了一个新版本的 Ziggurat 方法,用于生成给定递减密度函数的随机变量。它比原始方法更快、更简单,例如,在 400MHz 的 PC 机上,C 语言版本每秒可以生成 1500 万个正态或指数分布的随机变量。它使用了两个表,整数 ki 和实数 wi。大约 99% 的情况下,所需的 x 值通过以下方式生成:生成一个随机的 32 位整数 j,设 i 为 j 的最右边 8 位形成的索引。如果 j < ki,则返回 x = j . wi。

他们完成了 99.9% 的工作,我只是将他们的 C 代码封装在一个类包装器中。

直方图

为了说明这个生成器,我们还提供了一个名为 THistogram 的模板类。

一点数学背景

正态分布在概率和统计学中占有重要地位,这主要是因为中心极限定理,它是连接这两个学科的基本定理之一。

正态分布也称为高斯分布,以卡尔·弗里德里希·高斯的名字命名,他是最早使用该分布的人之一。

网上有很多关于正态分布的教程和演示小程序,所以我在这里不深入探讨数学细节。您可以在 概率和统计学虚拟实验室 找到一个非常好的网站。

用于计算均值、方差和其他统计特性的算法取自《数值分析》(见 [2])。

使用生成器

CRandomGenerator 提供了两种类型的随机变量:正态分布和指数分布。它们由两个 static 函数 RNORREXP 计算。

  • 标准正态变量
    float var = CRandomGenerator::RNOR();
    	
    您还可以修改生成器的均值和标准差。
    float fMean=...;
    float fSdev=...;
    float var = CRandomGenerator::RNOR(fMean, fSdev);	
  • 指数分布变量
    float var = CRandomGenerator::REXP();	

初始化生成器

与任何随机数生成器一样,它需要用一个“种子”进行初始化。传统上,人们使用当前时间来播种生成器。这在 CRandomGenerator 的默认构造函数中是隐式完成的,所以您需要在您的应用程序线程中使用该生成器之前,构建一个且仅一个 CRandomGenerator 对象。在 CWinApp::InitInstance 函数中这样做是个好主意。

CWinApp::InitInstance
{
   ...
   // build a CRandomGenerator to seed the generator
   CRandomGenerator randn;
}

使用直方图

THistogram 是一个模板化的直方图类。

模板参数

  • T,输入数据类型:可以是 floatdouble
  • TOut,结果数据类型:可以是 floatdouble,默认设置为 double

Characteristics

直方图的特点是:

  • 一个区域,由最小和最大谱值定义(参见 Get/SetMinSpectrum, Get/SetMaxSpectrum)。
  • 一个步长(参见 GetStep)。

Histogram diagram

计算直方图

您可以通过不同的方式向直方图提供数据:

  • 提供一组数据
    vector< float > vData;
    ...  // computing the data
    	 
    // Creating an histogram with 101 regions
    THistogram< float > histo(101);
    // Computing the histogram, min and max values are automatically computed... 
    histo.Compute( vData , true /* compute min, max */);
  • 用一组数据更新
    vector< float > vData;
    ... 
    // updating the histogram 
    histo.Update( vData );
    
  • 用单个数据项更新
    float fData;
    ... 
    // updating the histogram 
    histo.Update( fData );
  • 计算数据集的统计特性:您可以使用 static 方法 GetMoments 来计算数据集的矩(均值标准差方差等)。
    float fMean, fAdev, fSdev,  fVar, fSkew,fKurt;
    // Computing successively the mean, absolute mean, 
    // standard deviation, variance, skewness and kurtosis
    THistogram<float,float>::GetMoments(vData, fAdev, fSdev,fVar, fSkew, fKurt);
    该方法在演示中用于比较 CRandomGenerator 生成的正态分布和理论概率密度函数。

检索结果

  • 使用 GetHistogram 获取直方图结果。
  • 通过调用 GetNormalizedHistogram 获取归一化的直方图(使其面积为 1)。
  • 可以使用 GetLeftContainersGetCenterContainers 访问区域的坐标。

    用于生成图表的代码如下所示:

    vector < double > vDistribution ( histo.GetNormalizedHistogram() );
    vector < double > vLeftPositions ( histo.GetLeftContainers() );
    CPGLLine2D* pLine;
    ...
    pLine->SetDatas(vLeftPositions, vDistributions);

演示应用程序

演示应用程序显示了正态分布和指数分布。红线代表随机值的直方图,蓝线代表理论概率密度函数。

演示应用程序中有两个项目:

  • HistogramDemo 使用 Plot Graphic Library 进行可视化。关于 PGL 的另一篇文章可以在 这里找到。您需要 GDI+ 二进制文件才能使演示应用程序正常工作!(gdiplus.dll
  • HistogramMatlab 使用 Matlab 引擎进行可视化。您需要安装 Matlab 才能使演示应用程序正常工作!

请注意,源代码使用 Doxygen 语法进行了文档化。

参考文献

更新历史

  • 2002年11月26日
    • CRandomGenerator 中添加了理论分布。
    • 添加了直方图面积计算。
    • 修正了归一化直方图,添加了。
  • 2002年9月13日
    • 添加了一个使用 Matlab 的新演示项目。
  • 2002年9月11日
    • 修正了演示项目并在演示中添加了二进制文件。

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.