Documente Academic
Documente Profesional
Documente Cultură
Tehnici de Simulare
1
Formularea problemei 1
Considerente teoretice:
// normal_distribution
#include <iostream>
#include <string>
#include <random>
int main()
{
const int nrolls=100; // number of experiments
std::default_random_engine generator;
std::normal_distribution<double> distribution(2.5,5);
double p[100]={};
double media, dispersia, suma=0, var = 0;
int numar;
2
for (int i=0; i<nrolls; ++i) {
double number = distribution(generator);
p[i] = number;
}
}
media= suma / (double)nrolls;
for (int i=0; i<nrolls; ++i) {
var = var +pow((p[i] - media),2);
}
dispersia= var / (double)nrolls;
std::cout << "Media si dispersia " <<media <<" , "<< dispersia <<std::endl;
return 0;
}
Output:
normal_distribution (2.5,5):
1.89017
-2.93409
5.92145
-2.87595
2.66635
6.22418
2.66803
3
-0.133186
4.81266
3.5035
Media si dispersia 2.51659 , 26.692
Considerente teoretice:
Metoda polara este o generare a unei perechi de variabile aleatoare normale standard.
Metoda polară funcționează alegând punctele aleatorii ( x , y ) în pătratul -1 -1 x <1, -1 < y <1
până când:
0 < s = x2 + y2 < 1
Se returneaza perechea de variabile aleatoare normale:
−2ln (𝑠)
𝑥
𝑠
,
−2ln (𝑠)
𝑦
𝑠
Daca variabilele U1, U2 sunt uniforme pe [0, 1] si independente, atunci variabilele aleatoare
−2ln (𝑠)
𝑍1 = 𝑉1
𝑠
−2ln (𝑠)
𝑍2 = 𝑉2
𝑠
si sunt cosinusul si sinusul unghiului pe care vectorul (V1, V2) il face cu axa x.
√ √
Algoritm:
// normal_distribution
#include <iostream>
4
#include <string>
#include <random>
#include <cmath>
double generateGaussian(double mean, double stdDev) {
static double spare;
static bool hasSpare = false;
if (hasSpare) {
hasSpare = false;
return spare * stdDev + mean;
} else {
double u, v, s;
do {
u = ((double)( rand()% 1001) / 1000) * 2.0 - 1.0;
v = ((double)( rand()% 1001) / 1000) * 2.0 - 1.0;
s = u * u + v * v;
} while (s >= 1.0 || s == 0.0);
s = sqrt(-2.0 * log(s) / s);
spare = v * s;
hasSpare = true;
return mean + stdDev * u * s;
}
}
int main()
{
const int nrolls=100; // number of experiments
double p[100]={};
double media, dispersia, suma=0, var = 0;
int numar;
}
media= suma / (double)nrolls;
for (int i=0; i<nrolls; ++i) {
var = var +pow((p[i] - media),2);
}
dispersia= var / (double)nrolls;
5
std::cout << "Media si dispersia " <<media <<" , "<< dispersia <<std::endl;
return 0;
}
Output:
normal_distribution (2.5,5):
2.88825
2.79534
2.16604
2.51405
-3.97007
-0.272887
2.32672
2.71221
-1.42415
3.89724
Media si dispersia 2.72665 , 24.6144
Considerente teoretice:
care este termenul unei progresii geometrice (de aici provine denumirea acestei distributii).
Observam ca:
Algoritm:
#include <iostream>
#include <string>
#include <random>
int main()
6
{
const int nrolls=100; // number of experiments
std::default_random_engine generator;
std::geometric_distribution<int> distribution(0.3);
int p[100]={};
double media, dispersia, var = 0;
int suma=0;
}
media= suma / (double)nrolls;
for (int i=0; i<nrolls; ++i) {
var = var +pow((p[i] - media),2);
}
dispersia= var / (double)nrolls;
std::cout << "Media si dispersia " <<media <<" , "<< dispersia <<std::endl;
7
return 0;
}
Output:
geometric_distribution (0.3):
0
1
0
3
7
2
0
2
0
0
Media si dispersia 2.22 , 5.7716
Considerente teoretice:
Algoritm:
Intrare: p, q = 1 - p;
#include <iostream>
#include <random>
double U , X;
double uniform()
8
}
int main()
double p[100]={};
int numar;
U = uniform();
p[i]=U; X=round(log(U)/log(0.7))-1;
std::cout << "Media si dispersia " <<media <<" , "<< dispersia <<std::endl;
return 0;
9
Output:
geometric_distribution (0.3):
0.897
0.802
0.765
0.992
0.001
0.521
0.22
0.38
0.729
0.969
Media si dispersia 0.51314 , 0.0824105
10