#define frand() ((double) rand() / (RAND_MAX+1.0))To co? Jedziemy ? ;-) Teorii sobie i Wam oszczędzę... dociekliwych i z zacięciem matematycznym odsyłam do tej książeczki [2]. W niej to opisane są poniższe algorytmy. Kod zamieszczam jedynie w celach poznaczych, a studentów WSISIZ przestrzegam przed metodą Kopiego-Paste'a, bo się skończy brakem zaliczenia ;-)
Chcemy uzyskać generator o rozkładzie normalnym oraz Cauchy'ego... Na początek jednak jako podstawa potrzebny nam będzie generator o rozkładzie równomiernym.
Zdefiniujmy sobie klasę RandomNumberGenerator:
class RandomNumberGenerator {
private:
double a,b,c;
static RandomNumberGenerator* instance;
protected:
RandomNumberGenerator();
public:
static RandomNumberGenerator* getInstance();
void init();
double getFromUniformDistribution();
double getFromNormalDistribution();
double getFromCauchyDistribution();
};
Klasa jak widać będzie miała trzy metody do pobierania losowych wartości z różnych rozkładów. Zaimplementujmy pierwszy rozkład, używając do tego celu tzw. ogólnego generatora liniowego. Generator ten realizuje schemat liniowy:
Xn+1 = (a1Xn + a2Xn-1 + ... + akXn-k+1 + c) mod m
Przedstawiona w książce Wieczorkowskiego i Zielińskiego[2] implementacja generuje liczby z przedziału (-0.5, 0.5), dostosowałem ją więc tak aby przedział ten wynosił (0,1) - taki, jaki jest potrzebny do późniejszego użycia w generatorze o rozkładzie normalnym. Inicjacja generatora następuje w metodzie init(), a sam algorytm w metodzie getFromUniformDistribution():
#include <math.h>
#include <values.h>
#include <time.h>
#include "RandomNumberGenerator.h"
using namespace std;
RandomNumberGenerator* RandomNumberGenerator::instance = 0;
RandomNumberGenerator* RandomNumberGenerator::Instance(){
if (instance == 0){
instance = new RandomNumberGenerator;
instance->init();
}
return instance;
}
RandomNumberGenerator::RandomNumberGenerator(){}
void RandomNumberGenerator::init() {
a = time(NULL);
b = time(NULL);
c = time(NULL);
}
double RandomNumberGenerator::getFromUniformDistribution(){
static int n;
static double d,x;
d = (a + b + c) * 8192;
x = fmod (d,4294967291.0);
a = b; b = c; c= x;
if (x < (float) 2147483648.0) {
n = (int) x;
} else {
n = (int) (x - 4294967296.0);
}
return (n * 2.3283064365e-10 + 0.5);
}
CDN...
[1] http://pl.wikipedia.org/wiki/Generator_liczb_pseudolosowych
[2] "Komputerowe generatory liczb losowych" R. Wieczorkowski R Zieliński, WNT 1997

2 komentarze:
Witam. Program o generatorach wygląda dosyć ciekawie. Nie mogę go skompilować. Jeżeli jest możliwość to proszę o przesłanie gotowego projektu na maila. Będę wdzięczny. Pozdrawiam
E-mail: tom87[@]onet.eu
PS. bez nawiasów []
całość znajduje się na githubie: http://github.com/pmandes/RandomGen
kompilacja poleceniem make
Prześlij komentarz