如何生成均值为C+的随机数+;? 如何在1000到20000之间生成100个随机数,C++中的平均数为9000?我正在研究C++ 11库,但是没有找到一个允许我包含均值和范围的方法。< p>因为只要不满足分配,只要满足约束,到目前为止,最容易做的就是始终生成 9000 < /代码>。最简单的分布不是这样的,比如用概率产生1000,用概率产生p和20000用概率产生1-p,在这里你已经解出了p的值,得到了正确的平均值

如何生成均值为C+的随机数+;? 如何在1000到20000之间生成100个随机数,C++中的平均数为9000?我正在研究C++ 11库,但是没有找到一个允许我包含均值和范围的方法。< p>因为只要不满足分配,只要满足约束,到目前为止,最容易做的就是始终生成 9000 < /代码>。最简单的分布不是这样的,比如用概率产生1000,用概率产生p和20000用概率产生1-p,在这里你已经解出了p的值,得到了正确的平均值,c++,c++11,random,C++,C++11,Random,我强烈怀疑,在开始考虑编程之前,您应该先弄清楚您要做的事情的数学/统计信息。以下是如何使用正态分布,使用示例丢弃技术将值保持在范围内。这当然会扭曲分布,因此不再是正态分布。这种影响有多大取决于您对标准偏差的原始选择。这对你有多重要取决于你的申请 #include <iostream> #include <random> double get_random_number_with_minimum_mean_and_maximum( double minimum,

我强烈怀疑,在开始考虑编程之前,您应该先弄清楚您要做的事情的数学/统计信息。

以下是如何使用正态分布,使用示例丢弃技术将值保持在范围内。这当然会扭曲分布,因此不再是正态分布。这种影响有多大取决于您对标准偏差的原始选择。这对你有多重要取决于你的申请

#include <iostream>
#include <random>

double get_random_number_with_minimum_mean_and_maximum(
    double minimum,
    double mean,
    double maximum
) {

    // Any uniform random generator of your choice could be used here.
    // Obviously making this static is not rentrant or thread-safe.
    static std::mt19937 generator;

    // We'll start with a normal distribution with a standard deviation set
    // such that ~99.7% of the time we'll get a number within the average width
    // of your upper and lower bounds.
    //
    // Why ~99.7% and not some other number? Because that corresponds to three
    // standard deviations, and you didn't specify any requirements, so I'm
    // just making assumptions on your behalf.
    double const average_bound_width = ((mean-minimum) + (maximum-mean)) / 2;
    double const standard_deviation  = average_bound_width / 3;
    std::normal_distribution<double> distribution(mean, standard_deviation);

    // Now, keep fetching numbers until we find one that is within our desired
    // bounds. Throwing numbers away randomly from a normal distribution does
    // not affect the mean, but since our bounds are going to be skewed, our
    // mean will probably get skewed slightly, but this will likely not be
    // very noticable.
    double value;
    do {
        value = distribution(generator);
    } while (value < minimum || maximum < value);

    return value;
}

int main() {
    for (int i=0; i<100; ++i) {
        std::cout << get_random_number_with_minimum_mean_and_maximum(
            1000,
            9000,
            20000
        ) << '\n';
    }
}
平均值约为8980,仅100个样本就接近9000个


如果我用100万个样本来运行,平均值是~9049。

因为你在分布上很灵活,一个简单的解决方案仍然可以给出合理的结果,而不必做拒绝逻辑,这是一个很好的解决方案。也就是说,将三角形的下端设置为1000,将三角形的上端设置为20000,将三角形的尖端设置为9000

上面的维基百科链接表明三角形分布的平均值为:

(a + b + c) / 3
std::piecewise_linear_distribution<> dist({1000., 6000., 20000.},
                                          [](double x)
                                          {
                                              return x == 6000 ? 1. : 0.;
                                          });
其中
a
b
分别是您的下限和上限,
c
是三角形的尖端。对于您的输入,简单代数表明
c=6000
将给出您所需的平均值9000

在C++的
标题中有一个称为
std::piecewise\u linear\u distribution
的分布,非常适合设置三角形分布。这只需要两条直线。构造这种三角形分布的一种简单方法是:

(a + b + c) / 3
std::piecewise_linear_distribution<> dist({1000., 6000., 20000.},
                                          [](double x)
                                          {
                                              return x == 6000 ? 1. : 0.;
                                          });
如果将采样值的数量增加到足够高,您将看到参数收敛:

size = 10000000
min = 1003.08
avg = 8998.91
max = 19995.5
根据需要进行种子设定。

这是一个连续的,可以返回范围内的任何值,并且一次执行。平均值符合要求,但模式通常位于最接近平均值的两端

double shiftable_distribution(double minimum, double mean, double maximum)
{
    double range = maximum - minimum;
    double scaledmean = (mean - minimum) / range;
    return pow((double)rand() / RAND_MAX, 
               (1.0 - scaledmean) / scaledmean) 
                * range + minimum;
}
发行版的实际外观(对于1000、9000、20000)


您想要什么分发?任何分发都可以。在这种情况下,什么是最好的?如果你不知道你想要什么,你几乎肯定想要一个“正态分布”,也称为“高斯分布”。正态分布会给你一个10500((20000-1000)/2+1000)的平均值。如果平均值为9000,那么曲线会有轻微的偏差。几乎没有一个用例,其中一个特定的平均值会起作用,而分布是不相关的。你应该试着描述你的实际问题,这样我们才能给出有用的答案。你所说的相当于“我想生成一个包含'1'的数字,但我不在乎数字是以什么为基础写的。”如果我使用正态分布,我必须提供一个标准偏差,这会降低平均值,正确吗?我如何选择一个标准偏差,使生成器能够潜在地选取范围内的每个数字,但将平均值保持在9000?@user3647894简短回答:你不能。你必须“切掉”高斯曲线的尾部,这样你就不再有高斯曲线了。否则,高斯分布中的任何值都具有非零发生概率。
double shiftable_distribution(double minimum, double mean, double maximum)
{
    double range = maximum - minimum;
    double scaledmean = (mean - minimum) / range;
    return pow((double)rand() / RAND_MAX, 
               (1.0 - scaledmean) / scaledmean) 
                * range + minimum;
}