如何在1,000到20,000之间生成100个随机数,C++中的平均值为9,000?我正在研究C++ 11库,但我找不到允许我包含平均值和范围的方法.
小智 6
因为只要它满足你的约束你就不关心分布,到目前为止最简单的事情就是简单地生成9000
所有的时间.并且最简单的分布不是像1000
概率p
和20000
概率一样产生的东西1-p
,在那里你已经解决了它的值p
,给出了正确的均值.
我强烈怀疑你在开始考虑编程之前应该弄清楚你想要做的事情的数学/统计.
由于您可以灵活地进行分发,因此一个简单的解决方案仍能提供合理的结果,而不必采用拒绝逻辑,这是一种三角形分布.即你将三角形的下端设置为1,000,将三角形的上端设置为20,000,并将三角形的尖端设置为使得你想要的平均值为9,000.
上面的维基百科链接表明三角形分布的平均值是:
(a + b + c) / 3
Run Code Online (Sandbox Code Playgroud)
where a
和b
是你的下限和上限,并且c
是你的三角形的尖端.对于您的输入,简单代数表示c = 6,000
将给出您想要的平均值9,000.
在C++的<random>
头文件中有一个分布,称为std::piecewise_linear_distribution
设置三角形分布的理想选择.这只需要两条直线.构建这种三角形分布的一种简单方法是:
std::piecewise_linear_distribution<> dist({1000., 6000., 20000.},
[](double x)
{
return x == 6000 ? 1. : 0.;
});
Run Code Online (Sandbox Code Playgroud)
现在你只需要将URNG插入到这个发行版中并生成结果.为了理智,根据您的问题陈述收集一些重要的统计信息也很有帮助,例如最小值,最大值和平均值.
这是一个完整的程序,它执行此操作:
#include <algorithm>
#include <iostream>
#include <numeric>
#include <random>
#include <vector>
int
main()
{
std::mt19937_64 eng;
std::piecewise_linear_distribution<> dist({1000., 6000., 20000.},
[](double x)
{
return x == 6000 ? 1. : 0.;
});
std::vector<double> results;
for (int i = 0; i < 100; ++i)
results.push_back(dist(eng));
auto avg = std::accumulate(results.begin(), results.end(), 0.) / results.size();
auto minmax = std::minmax_element(results.begin(), results.end());
std::cout << "size = " << results.size() << '\n';
std::cout << "min = " << *minmax.first << '\n';
std::cout << "avg = " << avg << '\n';
std::cout << "max = " << *minmax.second << '\n';
}
Run Code Online (Sandbox Code Playgroud)
这应该可以输出:
size = 100
min = 2353.05
avg = 8972.1
max = 18162.5
Run Code Online (Sandbox Code Playgroud)
如果您将采样值的数量调高到足够高,您将看到参数收敛:
size = 10000000
min = 1003.08
avg = 8998.91
max = 19995.5
Run Code Online (Sandbox Code Playgroud)
根据需要种子.