3 Ağustos 2017 Perşembe

Random Number Generator Kullanımı

Giriş
Random sayı üreteçleri genellikle [0,1) arasında bir sayı üretirler. Eğer aralığı [min,max) yapmak istiyorsak aşağıdaki formülü kullanırız.
min + Math.random() * (max - min)
Random Sayı Üretecinin Tarihçesi
Tarihsel olarak şu Random sayı üreteçleri kullanılmış.
Historically three types of random number generators have been advocated for computational applications: (a) 1950's-style table look-up generators like, for example, the RAND corporation table of a million random digits; (b) hardware generators like, for example, thermal "white noise" devices; and (c) algorithmic (software) generators. Of these three types, only algorithmic generators have achieved widespread acceptance. The reason for this is that only algorithmic generators have the potential to satisfy all of the following generally well-accepted random number generation criteria. A generator should be:
  • random - able to produce output that passes all reasonable statistical tests of randomness;
  • controllable - able to reproduce its output, if desired;
  • portable - able to produce the same output on a wide variety of computer systems;
  • efficient - fast, with minimal computer resource requirements;
  • documented - theoretically analyzed and extensively tested.
Linear Congruential Generator
Random sayı üreteçlerinin çoğunda kullanılan algoritma Linear Congruential Generator denilen metoda dayanıyor. Bu algoritmada x'=(a*x+c) mod m formülü kullanıldığı için, üretilen sayı mod m değerine ulaşıncaya kadar artarak ilerler. Üretilen sayılar plot edilirse birbirlerine paralel çizgiler görülebilir.

233280'e (6 hane) kadar sayı üreten bir örnek
(Math.seed * 9301 + 49297) % 233280
1013904233'e (10 hane) kadar sayı üreten bir örnek
seed = 1664525 * seed % 1013904223;
LCG kullanan algoritmaların istatistiki anlamda bazı zayıflıkları vardır. Örneğin birbirlerine yakın seedler kullanan üreteçler yakın sonuçlar üretirler.

Kriptografik Generator
Kriptografik Random Number Generator Kullanımı yazısına taşıdım.

Windows
Windows üzerinde rand_s metodu 32 bitlik sayılar üretir. Bu üreteci de yine srand() ile başlatmak gerekebilir.

Ayrıca CryptGenRandom ile daha güvenli sayılar üretmek te mümkün. Örnek:
#include<Wincrypt.h>

HCRYPTPROV hCryptProv;
union {
    BYTE bs[sizeof(long int)];
    long int li;
} rand_buf;
CryptGenRandom(hCryptProv, sizeof(rand_buf), &rand_buf);
printf("Random number: %ld\n", rand_buf.li);
rand_r - obsolete
rand_r metodu yazısına taşıdım.

drand48
drand48 ile [0.0 , 1.0) aralığında double sayılar üretilir.


C#
NextDouble() metodu ile [0.0 , - 1)  aralığında sayı üretilir. Java'daki eşleniği ile aynı işi yapar. How do you generate a random number in C#? sorusuna verilen çözüm ile istenilen aralıkta [min,max] sayı üretmek mümkün.
Next(Int32 max) metodu ile [0,max) aralığında sayı üretir. Java'daki eşleniği ile aynı işi yapar. Örnek:
Random rand = new Random();
rand.Next(6);

Linux /dev/urandom
Kriptografik Random Number Generator Kullanımı yazısına taşıdım.

Linux /dev/random
/dev/random ve /dev/urandom arasındaki farkı görmek için buraya bakınız. Şöyle yaparız.
void randomize() {
  uint32_t seed=0;
  FILE *devrnd = fopen("/dev/random","r");
  fread(&seed, 4, 1, devrnd);
  fclose(devrnd);
  srand(seed);
}
boost
üreteç sınıfları
boost ile bir çok random sayı üreten sınıf geliyor. Her üreteç bir dağılım sınıfı ile beraber kullanılınca ortaya çok kolay bir yapı çıkıyor.
mt19937
Örnekleri Getting integer random values instead of real values using boost::random library sorusundan aldım. Aşağıdaki üreteç Mersenne twister algoritmasını kullanıyor

mt19937 sınıfının discard() diye bir metodu var. Bu metod ile verilen miktar kadar sayı üretilmiş gibi yapılabiliyor. Örnek:
std::mt19937 engine(time(0));
engine.discard(10000000);
lagged_fibonacci607

Bir başka örnekte ise Lagged Fibonacci algoritmasını kullanılıyor.
dağılım sınıfları
boost ile bir çok farklı dağılım sınıfı geliyor.

uniform_real_distribution : [min..max) aralığında Random Distribution floating point değer döndürür.

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random/uniform_real_distribution.hpp>

boost::mt19937 gen;

int roll_die() {
    boost::uniform_real_distribution<> dist(1, 6);
    boost::variate_generator<boost::mt19937&, boost::uniform_real<> > die(gen, dist);
    return die();
}

uniform_01 : [0..1) aralığında Random Distribution floating point değer döndürür

bernoulli distribution
bernoulli dağılımı en basit dağılım.

binomial deviation
Bu dağılım kısaca Bernouilli dağılımına dayanan bir olayların sırasına bakmaksızın arka arkaya olma dağılımı. Paranın yazı tura gelmesi, torbadan topun çekilip tekrar torbaya konulması gibi birbirini etkilemeyen olaylarda kullanılır.

Örnek:
#include <boost/math/distributions/binomial.hpp>
using boost::math::binomial;
const double success_fraction = 0.5; // = 50% = 1/2 for a 'fair' coin.
int flips = 10;
binomial flip(flips, success_fraction);
//get mean, standart deviation etc

discrete_distribution
discrete_distribution [0..n) aralığında Random Distribution integer değer döndürür.

Generating random numbers in a range with a predefined, non-uniform probability örneğinde yüzde dağılım listesi kullanan bir örnek te mevcut.

normal_distribution
normal_distribution verilen ortalama ve standart sapmada , Gauss dağılım integer değer döndürür. Normal dağılım ve Gauss Dağılım (Normal Distribution ve Gaussian Distribution) aynı şeylerdir. Bence Gauss dağılımı kelimesini kullamak daha iyi, çünkü normal kelimesi çok fazla anlam yüklü bir kelime.

Standart normal dağılım, ortalaması 0 standart sapması 1 olan dağılımdır. Aşağıdaki şekil standart normal dağılım gösteriyor. Eğer standart sapma büyürse değerlerin ortalamadan daha çok uzaklaştıkları sonucuna varabiliriz, bu da çan eğrisinin basık olduğunu gösterir.


How to write a controllable random number generator? sorusunda ise normal_distribution örneği verilmiş.

Gaus dağılımı Kalman filtresinde kullanılır. Bu filtrede input, noise, measurement noise ve initial state değerlerinin gaus dağılımında olduğu ve birbirlerinden bağımsız oldukları varsayılır.
Aşağıdaki denklem Kalma filtresinin ilk denklemi.

x (k-1) bir önceki state, Buk kontrol sinyali , wk-1 ise mesurement noise olarak tanımlanır.



Apache Commons
Poissson
PoissonDistribution Sınıfı yazısına taşıdım

NormalDistribution
Bu sınıf ile ilgili örnek koymam lazım.

multivariate normal distribution
MultivariateNormalDistribution sınıfı ile yapılıyor. Bu dağılımla ilgili bilgi yazmam lazım.

bash
bash ile rastgele sayı üretmek için $(RANDOM) kullanılır. [0-32767] arasında bir sayı üretir.
echo "file$((RANDOM % 4)).jpg"

Hiç yorum yok:

Yorum Gönder