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

时间:2015-02-19 23:18:55

标签: c++ c++11 random normal-distribution

我需要生成遵循正态分布的随机数,该分布应该在1000和11000之间,平均值为7000.我想使用c++11 library function,但我不知道如何生成数字在这段时间内。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

您没有指定标准偏差。假设给定间隔的标准偏差为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与平均值相差3个标准偏差。通过这些设置,我们将仅丢弃生成值的0.3%。所以你可以添加以下构造函数:

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

并将生成器初始化为:

Generator g(1000.0, 11000.0);

答案 1 :(得分:1)

正态分布由两个数字决定:均值和方差。 (见Wikipedia)。您可以限制输出,但它不再是正态分布。如果标准偏差远小于您的间隔,则这种差异是微不足道的。处理它的一种方法是拉随机数,如果它在区间之外,则将其固定到间隔边缘。这会在你的间隔边缘产生很小的概率峰值。数学上更好的方法(虽然计算上可能很糟糕)是抛出区间之外的任何值并绘制另一个值。这会截断您的分布,而不会改变它的形状(除了规范化)。这是你如何做到这一点。我没有测试它。

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 )

答案 2 :(得分:0)

在这里您可以找到随机数生成器的库: http://www.agner.org/random/?e=0,31 例如,截断的正态分布在stocc库中实现: http://www.agner.org/random/stocc.zip