Creating a Gaussian Random Generator with a mean and standard deviation
Solution 1
In C++11 this is relatively straight forward using the random header and std::normal_distribution (live example):
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 e2(rd());
std::normal_distribution<> dist(70, 10);
std::map<int, int> hist;
for (int n = 0; n < 100000; ++n) {
++hist[std::round(dist(e2))];
}
for (auto p : hist) {
std::cout << std::fixed << std::setprecision(1) << std::setw(2)
<< p.first << ' ' << std::string(p.second/200, '*') << '\n';
}
}
If C++11 is not an option than boost also provides a library(live example):
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>
int main()
{
boost::mt19937 *rng = new boost::mt19937();
rng->seed(time(NULL));
boost::normal_distribution<> distribution(70, 10);
boost::variate_generator< boost::mt19937, boost::normal_distribution<> > dist(*rng, distribution);
std::map<int, int> hist;
for (int n = 0; n < 100000; ++n) {
++hist[std::round(dist())];
}
for (auto p : hist) {
std::cout << std::fixed << std::setprecision(1) << std::setw(2)
<< p.first << ' ' << std::string(p.second/200, '*') << '\n';
}
}
and if for some reason neither of these options is possible then you can roll your own Box-Muller transform, the code provided in the link looks reasonable.
Solution 2
Use the Box Muller distribution (from here):
double rand_normal(double mean, double stddev)
{//Box muller method
static double n2 = 0.0;
static int n2_cached = 0;
if (!n2_cached)
{
double x, y, r;
do
{
x = 2.0*rand()/RAND_MAX - 1;
y = 2.0*rand()/RAND_MAX - 1;
r = x*x + y*y;
}
while (r == 0.0 || r > 1.0);
{
double d = sqrt(-2.0*log(r)/r);
double n1 = x*d;
n2 = y*d;
double result = n1*stddev + mean;
n2_cached = 1;
return result;
}
}
else
{
n2_cached = 0;
return n2*stddev + mean;
}
}
you can read more at: wolframe math world
Solution 3
In C++11 you would use the facilities provided by the <random>
header; create a random engine (e.g. std::default_random_engine
or std::mt19937
, initialized with std::random_device
if necessary) and a std::normal_distribution
object initialized with your parameters; then you can use them together to generate your numbers. Here you can find a full example.
In previous versions of C++, instead, all you have is the "classic" C LCG (srand
/rand
), which just generates a plain integer distribution in the range [0, MAX_RAND]; with it you can still generate gaussian random numbers using the Box-Muller transform. (It might be useful to note that the C++11 GNU GCC libstdc++'s std::normal_distribution
uses the Marsaglia polar method as shown herein.).
Solution 4
With #include <random>
std::default_random_engine de(time(0)); //seed
std::normal_distribution<int> nd(70, 10); //mean followed by stdiv
int rarrary [101]; // [0, 100]
for(int i = 0; i < 101; ++i){
rarray[i] = nd(de); //Generate numbers;
}
coder_For_Life22
https://plus.google.com/u/0/stream#105618653157264956200/posts
Updated on July 09, 2022Comments
-
coder_For_Life22 almost 2 years
I am trying to create a one dimensional array and use a random number generator(Gaussian generator that generates a random number with means of 70 and a standard deviation of 10) to populate the array with at least 100 numbers between 0 and 100 inclusive.
How would i go about doing this in C++?