从 Boost Pareto 分布中随机生成的数字

Randomly Generated Numbers from Boost Pareto Distribution

所以在问这个问题之前,我仔细查看了堆栈溢出和 google。我有一个正在处理的模拟,需要能够生成 0 到 1.0 之间的随机输入数据,这些数据遵循特定的统计分布。

到目前为止,我已经得到了正常工作的正态分布和均匀实数分布,但仍然坚持帕累托分布。

前两个在 boost/random/ 中可用,但 pareto 仅可作为原始分布使用(即不可用于变量生成器)。有谁知道生成所述随机数的方法?请注意,我已经倾注了 boost 文档,包括 Pareto 分布。我希望生成 遵循 帕累托分布的随机数, 而不是 使用帕累托分布来确定统计概率。到目前为止我唯一能想到的就是使用统一生成器并将这些值插入 Pareto 分布的 CDF(但必须有比这更好的方法)。

任何帮助将不胜感激,因为我是新手。

谢谢!

这是我用于前两个的代码,与变体生成器一起使用。这都是非常多的测试代码,所以请不要在风格或约定上敲打我:

#include <time.h>
#include <iostream>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/math/distributions/pareto.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>

int main(){
    boost::mt19937 randGen(time(0));

    boost::normal_distribution<> dist1(.5,.2);
    boost::random::uniform_real_distribution<> dist2(0.0,1.0);

    boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > generator1(randGen,dist1);
    boost::variate_generator<boost::mt19937&,boost::random::uniform_real_distribution<> > generator2(randGen,dist2);

    for(int x = 0; x < 10; x++)
        std::cout << generator1() << std::endl;

    std::cout << "\n\n\n";

    for(int x = 0; x < 10; x++)
        std::cout << generator2() << std::endl;

    return 0;
}

The pareto distribution is related to the exponential distribution. So you could use boost to generate random values which follow an exponential distribution and manually calculate pareto distributed values from them. This question 您可能也会感兴趣。

在做了更多研究并咨询了统计部门的一些人之后,我找到了一种使用 uniform_real 分布来实现此目的的方法。我最初尝试使用分位数函数,如 this post 中所述,但结果总是得到 1 或 0 的字符串。

经过一些额外的试验和错误后,我发现基本上您需要做的就是将均匀实随机的结果插入 cdf 补函数。

Boost 的有趣之处在于它使用非成员函数来计算 cdf 值,因此 cdf 不是 parteo 分布本身的 属性。相反,在 boost 中执行此操作的正确方法是:

#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/math/distributions/pareto.hpp>

int main(){
     boost::mt19937 randGen(15); //held constant for repeatability
     boost:math::pareto_distribution<> dist;
     boost::random::uniform_real_distribution<> uniformReal(1.0,10.0); //this range can be adjusted to effect values

     boost::variate_generator<boost::mt19937&,boost::random::uniform_real_distribution<> > generator(randGen, dist);

     double cdfComplement;
     for(int i = 0; i < 5000; i++){
          cdfComplement = boost::math::cdf(complement(dist,generator()));
          //do something with value
     }         

     return 0;
}

到目前为止,我还没有找到将分布值限制在 0.0 到 1.0 范围内的好方法。有些离群值略低于 0.0,有些则刚好超过 1.0(尽管这完全取决于您输入的实数范围)。您可以轻松丢弃超出您要查找的范围的值。

我能够使用默认形状参数和上述方法获得这些结果。显示了 5,000 个数据点: