C++ - generate random numbers following normal distribution within range

烈酒焚心 提交于 2020-02-20 09:14:10

问题


I need to generate random numbers that follow a normal distribution which should lie within the interval of 1000 and 11000 with a mean of 7000. I want to use the c++11 library function but I am not understanding how to generate the numbers within the interval. Can someone help?


回答1:


You don't specify the standard deviation. Assuming a standard deviation of 2000 for the given interval you can try this:

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

Possible output:

4520.53
6185.06
10224
7799.54
9765.6
7104.64
5191.71
10741.3
3679.14
5623.84

If you want to specify only the min and max values, then we can assume that the mean value is (min + max) / 2. Also we can assume that min and max are 3 standard deviations away from the mean value. With these settings we are going to throw away only 0.3% of the generated values. So you can add the following constructor:

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

and initialize the generator as:

Generator g(1000.0, 11000.0);



回答2:


A normal distribution is determined by two numbers: a mean, and a variance. (see Wikipedia). You can limit the output, but it is no longer a normal distribution. If the standard deviation is much smaller than your interval this difference is trivial. One way to handle it is to pull a random number and if it is outside the interval fix it to the interval edge. This would put little spikes of probability at the edge of your intervals. A better way mathematically (although potentially bad computationally) is to throw out any value outside the interval and draw another one. This has the effect of truncating your distribution without changing it's shape (other than a normalization). Here is how you might do that. I didn't test it.

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 )



回答3:


Here you can find libraries for random number generators: http://www.agner.org/random/?e=0,31 For instance, truncated normal distribution is implemented in stocc library: http://www.agner.org/random/stocc.zip



来源:https://stackoverflow.com/questions/28618900/c-generate-random-numbers-following-normal-distribution-within-range

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!