C++ - 在范围内生成正态分布的随机数

5
我需要生成符合正态分布的随机数,其应在1000至11000之间,平均值为7000。我想使用c++11库函数,但我不明白如何在该区间内生成数字。有人能帮忙吗?

4
正态分布没有最小值或最大值。 - Oliver Charlesworth
1
你确定你需要的是正态分布吗?它在两个方向上都是无限的。http://en.wikipedia.org/wiki/Normal_distribution - pts
3
也许你需要一个截断正态分布。http://en.wikipedia.org/wiki/Truncated_normal_distribution - amdn
@AustinMullins 如果它代表sigma点,是否可以使用C++11库完成? - ChaniLastnamé
在“模拟”部分中有C++实现,但相当复杂... http://en.wikipedia.org/wiki/Truncated_normal_distribution#Simulating - amdn
显示剩余3条评论
3个回答

4

您没有指定标准差。假设给定区间的标准差为2000,您可以尝试以下方法:

#include <iostream>
#include <random>

class Generator {
    std::default_random_engine generator;
    std::normal_distribution<double> distribution;
    double min;
    double max;
public:
    Generator(double mean, double stddev, double min, double max):
        distribution(mean, stddev), min(min), max(max)
    {}

    double operator ()() {
        while (true) {
            double number = this->distribution(generator);
            if (number >= this->min && number <= this->max)
                return number;
        }
    }
};

int main() {
    Generator g(7000.0, 2000.0, 1000.0, 11000.0);
    for (int i = 0; i < 10; i++)
        std::cout << g() << std::endl;
}

可能的输出:

4520.53
6185.06
10224
7799.54
9765.6
7104.64
5191.71
10741.3
3679.14
5623.84

如果你只想指定 minmax 值,那么我们可以假设平均值为 (min + max) / 2。同时,我们也可以假设 minmax 相对于平均值来说是三倍标准差之外的。使用这些设置,我们将仅丢弃生成值的0.3%。因此,您可以添加以下构造函数:

Generator(double min, double max):
        distribution((min + max) / 2, (max - min) / 6), min(min), max(max)
    {}

并将生成器初始化为:

Generator g(1000.0, 11000.0);

在operator()()中的return number之后,难道不需要一个break语句吗? - Mattia
2
返回是绝对的中断 :) - JuniorCompressor
不要使用这种方法。对于许多情况来说它非常低效。很多人会遇到问题。 - Brans Ds

3
一般分布由两个数确定:平均值和方差。如果限制输出,则不再是正常分布(参见维基百科)。如果标准偏差远小于区间,则此差异微不足道。处理它的一种方法是随机抽取一个数字,如果超出区间,则将其修复到区间边缘。这会在区间边缘产生小的概率峰。从数学上讲,更好的方法(尽管在计算上可能很糟糕)是丢弃区间外的任何值并重新绘制另一个值。这会截断您的分布而不改变其形状(除了归一化)。以下是如何执行此操作的示例代码。我没有测试它。
std::default_random_engine generator;
std::normal_distribution<double> distribution(7000.0,100.0);
double sample;
do{
    sample= distribution(generator);
}while( sample<1000.0 || sample>11000.0 )

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接