Sunteți pe pagina 1din 10

Proiect

Tehnici de Simulare

Nume student : Munteanu Valentin


Nr. Proiect : 1
Grupa : an 3, Informatica, sectia ID

1
Formularea problemei 1

1. Sa se genereze variabila normala N (2:5; 5) cu ajutorul limitei centrale , variabila normala cu


ajutorul metodei polare . Sa se genereze variabila geometrica prin doua metode.

1.1 Sa se genereze variabila normala N (2,5; 5) cu ajutorul limitei centrale.

Considerente teoretice:

O variabila are repartitia normala daca are densitatea de repartitie:

m =medie; s =devierea standard, Var(X) = s2

Considerente despre algoritm:

Nu exista algoritm in pseudocod in curs deci se pot utiliza bibliotecile C++


Se vor face calculul mediei si dispersiei de selectie

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

std::cout << "normal_distribution (2.5,5):" << std::endl;


//primele 10 variabile
for (int i=0; i<10; ++i) {
std::cout << p[i] << std::endl;
}
for (int i=0; i<nrolls; ++i) {
double number = distribution(generator);
p[i] = number;
}
for (int i=0; i<nrolls; ++i) {
suma = suma +p[i];

}
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

Exit code: 0 (normal program termination)

1.2 Sa se genereze variabila normala cu ajutorul metodei polare .

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
𝑠

sau echivalent −2 ln (𝑠) −2 ln (𝑠)


√ √

cu V1 = 2U1 – 1, V2 = 2U2 – 1, S = V12 + V22, S<1 sunt variabile N(0,1) independente..

si sunt cosinusul si sinusul unghiului pe care vectorul (V1, V2) il face cu axa x.
√ √

Pentru a obtine variabila normala N(m, s) notata cu Y aplicam Y = m + sX.

Pentru a obtine direct variabila normala N(m, s) se poate aplica codul:

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;

for (int i=0; i<nrolls; ++i) {


double number = generateGaussian(2.5,5);
p[i] = number;
}

std::cout << "normal_distribution (2.5,5):" << std::endl;


//primele 10 variabile
for (int i=0; i<10; ++i) {
std::cout << p[i] << std::endl;
}

for (int i=0; i<nrolls; ++i) {


suma = suma +p[i];

}
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

Exit code: 0 (normal program termination)

1.3. Sa se genereze variabila geometrica prin doua metode.

1.3.a Metoda care utilizeaza distributia Pascal.

Considerente teoretice:

Aceasta metoda de generare este un caz particular de distributie Pascal pentru k = 1.

Atunci functia de probabilitate devine pentru k = 1:

P(X = x) = pqx, x =0,1.2 …

care este termenul unei progresii geometrice (de aici provine denumirea acestei distributii).

Observam ca:

F(x) = ∑ 𝑝𝑞I = 1-qx+1, E(X) = q/p, Var(X) = q/p2.

Metoda produce numere positive intregi aleatoare.

Parametrul algoritmului este probabilitatea p <1.

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;

for (int i=0; i<nrolls; ++i) {


int number = distribution(generator);
p[i] = number;
}

std::cout << "geometric_distribution (0.3):" << std::endl;


//primele 10 variabile
for (int i=0; i<10; ++i) {
std::cout << p[i] << std::endl;
}

for (int i=0; i<nrolls; ++i) {


suma = suma +p[i];

}
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

Exit code: 0 (normal program termination)

1.3.b Metoda geometrica de obtinere a variabilelor care utilizeaza metoda inversa.

Considerente teoretice:

Algoritm:

Intrare: p, q = 1 - p;

P1: Se genereaza U(0, 1);

P2: X := partea intreaga( log U / log q ) – 1.

Iesire: Variabila aleatoare X .

// geometric_distribution dupa metoda inversa

#include <iostream>

#include <random>

double U , X;

// generare nr aleatoare intre 0 si 1

double uniform()

return (double)( rand()% 1001) / 1000 ;

8
}

int main()

const int nrolls = 100; // number of experiments

double p[100]={};

double media, dispersia, suma=0, var = 0;

int numar;

//Consideram probabilitatea p=0.7 deci q=1-0.3 = 0.7

for (int i=0; i<nrolls; ++i) {

U = uniform();

p[i]=U; X=round(log(U)/log(0.7))-1;

std::cout << "geometric_distribution (0.3):" << std::endl;

//tiparim primele 10 valori aleatoare

for (int i=0; i<10; ++i)

std::cout << p[i] << std::endl;

for (int i=0; i<nrolls; ++i) {

suma = suma +p[i];

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;

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

Exit code: 0 (normal program termination)

10

S-ar putea să vă placă și