所以我在问这个问题之前做了相当多的环顾堆栈溢出和google。我正在进行模拟,需要能够生成0到1.0之间的随机输入数据,这些数据遵循某些统计分布。
到目前为止,我已经得到了正常的分布和统一的实际分布正常工作,但我仍然坚持帕累托分布。
前两个在boost / random /中可用,但是pareto仅作为原始分布提供(即不能在variate生成器中使用)。有谁知道生成所述随机数的方法?请注意,我已经倾倒了提升文档,包括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;
}
答案 0 :(得分:1)
The pareto distribution is related to the exponential distribution.因此,您可以使用boost生成遵循指数分布的随机值,并手动计算它们的pareto分布值。 This question也可能对你感兴趣。
答案 1 :(得分:0)
在做了一些研究并咨询统计部门的一些人后,我找到了一种方法,使用uniform_real发布。我最初尝试使用分位数函数,如this帖子中所述,但总是得到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个数据点: