J'essaie de créer un tableau unidimensionnel et d'utiliser un générateur de nombres aléatoires (générateur gaussien qui génère un nombre aléatoire avec des moyens de 70 et un écart-type de 10) pour remplir le tableau avec au moins 100 nombres entre 0 et 100 inclus.
Comment pourrais-je faire cela en C++?
En C++ 11 c'est relativement simple en utilisant en-tête aléatoire et std :: normal_distribution = (exemple en direct):
#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';
}
}
Si C++ 11 n'est pas une option, alors boost fournit également un bibliothèque (exemple en direct):
#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';
}
}
et si pour une raison quelconque aucune de ces options n'est possible, alors vous pouvez rouler la vôtre transformation Box-Muller , le code fourni dans le lien semble raisonnable.
Utilisez la distribution Box Muller (de ici ):
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;
}
}
vous pouvez en savoir plus sur: wolframe math world
En C++ 11, vous utiliseriez les fonctionnalités fournies par le <random>
entête; créer un moteur aléatoire (par exemple std::default_random_engine
ou std::mt19937
, initialisé avec std::random_device
si nécessaire) et un std::normal_distribution
objet initialisé avec vos paramètres; vous pouvez ensuite les utiliser ensemble pour générer vos numéros. Ici vous pouvez trouver un exemple complet.
Dans les versions précédentes de C++, à la place, tout ce que vous avez est le C LCG "classique" (srand
/Rand
), qui génère simplement une distribution entière simple dans la plage [0, MAX_Rand]; avec lui, vous pouvez toujours générer des nombres aléatoires gaussiens en utilisant transformée de Box-Muller . (Il peut être utile de noter que le C++ 11 GNU GCC libstdc ++'s std::normal_distribution
utilise la méthode polaire de Marsaglia comme indiqué ici .).
Avec #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;
}