如何用C ++中的平均值生成随机数字? [英] How do I generate random numbers with a mean in C++?

查看:411
本文介绍了如何用C ++中的平均值生成随机数字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在1,000到20,000之间生成100个随机数,C ++中的总平均值为9,000?我正在调查C ++ 11库,但没有找到一个允许我包括平均值和范围的方法。

How do I generate 100 random numbers in between 1,000 and 20,000, with a total mean of 9,000 in C++? I am looking into the C++ 11 Libraries but am not finding a method that allows me to include a mean AND a range.

推荐答案

由于您灵活的分发,一个简单的解决方案仍能提供合理的结果,而不必执行拒绝逻辑,这是一个三角分布。也就是说您将三角形的下端设置为1,000,三角形的上端设置为20,000,并将三角形的顶端设置为您希望的平均值为9,000。

Since you are flexible on distribution, an easy solution that still gives reasonable results, without having to do rejection logic, is a triangular distribution. I.e. you set the lower end of the triangle at 1,000, the upper end of the triangle at 20,000, and the tip of the triangle such that you get your desired mean of 9,000.

上面的维基百科链接表示三角分布的平均值是:

The wikipedia link above indicates that the mean of a triangular distribution is:

(a + b + c) / 3

其中 a b 分别是您的下限和上限, c 是三角形的尖端。对于您的输入,简单代数表示 c = 6,000 将给出您所需的平均值9,000。

where a and b are your lower and upper limits respectively, and c is the tip of your triangle. For your inputs, simple algebra indicates that c = 6,000 will give your desired mean of 9,000.

分布在C ++的< random> 头中,称为 std :: piecewise_linear_distribution ,非常适合设置三角分布。这只需要两条直线。构造这样的三角分布的一个简单方法是:

There is a distribution in C++'s <random> header called std::piecewise_linear_distribution that is ideal for setting up a triangular distribution. This needs only two straight lines. One easy way to construct such a triangular distribution is:

std::piecewise_linear_distribution<> dist({1000., 6000., 20000.},
                                          [](double x)
                                          {
                                              return x == 6000 ? 1. : 0.;
                                          });

现在,您只需要将URNG插入此分发版并找出结果。为了理智的缘故,收集一些根据你的问题陈述是重要的统计数据,如最小值,最大值和平均值也是有帮助的。

Now you simply have to plug a URNG into this distribution and crank out the results. For sanity's sake it is also helpful to collect some statistics that are important according to your problem statement, such as minimum, maximum, and mean.

这里是一个完整的程序这样做:

Here is a complete program that does this:

#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';
}

应该可移植地输出:

size = 100
min = 2353.05
avg = 8972.1
max = 18162.5

如果您将抽样值的数量提高到足够高,您将看到参数收敛:

If you crank up the number of sampled values high enough, you will see convergence on your parameters:

size = 10000000
min = 1003.08
avg = 8998.91
max = 19995.5

根据需要种子。

这篇关于如何用C ++中的平均值生成随机数字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆