4 Eylül 2017 Pazartesi

C++ ile Random Number Generator

C++11 ile eskiden sadece boost'un sağladığı birçok sınıf geliyor. Rastgele sayılar ile çalışırken çakışmalara hazırlıklı olmak gerekir.

Üreteç sınıfları - Generators

Generator sınıflarının amacı sayı üretmektir. İki çeşit üreteç var. Bunlar true random generator ve pseudo random number generator olarak sınıflandırılıyorlar.

true random number generator sınıflar donanım tabanlı ve yavaşlar. pseudo olanlar ise yazılım tabanlı ve hızlılar ancak daha kötü dağılım sağlıyorlar. Aşağıdaki şekillerde fark görülebilir.

True Random Number - Donanım Tabanlı


Pseudo Random Number - Yazılım Tabanlı

True Random Generator 
std::random_device yazısına taşıdım.

Pseudo Generator Sınıfları
Bu sınıfların isimleri _engine kelimesi ile biter.

İlklendirme
Pseudo random engine sınıflarını ilklendirmek için üç yöntem var. İlki true random generator kullanmak. Bu bence iyi bir fikir.
std::random_device rd;
std::mt19937 gen(rd());
İkincisi ise saati kullanmak. Ben bu fikri pek sevmiyorum. Bir başka örnek burada.
#include <random>
#include <chrono>

auto seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
C kodu kullanarak ilklendirmek için şöyle yaparız.
std::mt19937 generator(clock());
Üçüncüsü ise ilklendirmemek. Bu durumda default bir seed ile ilklenir. Bu zaten en kötü fikir.

1. default_random_engine
std::default_random_engine yazısına taşıdım.

2. mersenne_twister_engine 

1. mt19937
std::mt19937 yazısına taşıdım.

3. linear_congruential_engine
Bu sınıfın özelleşmiş hallerinden bir tanesi min_std_rand0. Bu sınıf şöyle tanımlı
linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647> minstd_rand0;
Sabitler sırasıyla a,c,m olarak anılıyor. Kullanılan formül şöyle
(a*x+c)%m

Sabitlerin base 8 olması gerektiği söyleniyor ancak ne kast edildiğini anlamadım

Dağılım Sınıfları - Distributions
Dağılım sınıflarının amacı üreteçlerin verdiği sayıları belli bir örüntüye göre (Uniform, Normal, Binomial) dağıtmaktır. Her dağılım sınıfı constructor metodu bir engine ile beraber çalışır.

  • Uniform Distribution - Tek Düze Dağılım demektir
  • Normal Distribution - Çan eğrisi dağılım demektir. Gaussian olarak ta bilinir. 
  • Bernoulli - Binomial Distribution - Binom dağılım demektir
  • Rate based Distribution 
  • Piecewise Distribution 
  • Canonical Number
gibi sınıflar var.

Nasıl Kullanırız


Dağılım sınıflarının constructor metodlarına aralık girilir. Daha sonra distribution sınıflarının () metodu verilen üreteci kullanarak sayı döndürür.

normal_distribution
normal_distribution Sınıfı yazısına taşıdım

uniform_int_distribution
uniform_int_distribution Sınıfı sınıfı yazısına taşıdım.

uniform_real_distribution
uniform_real_distribution Sınıfı yazısına taşıdım.

discrete_disctribution
discrete_disctribution Sınıfı yazısına taşıdım.

Engine Adapters
  • Discard Block Engine 
  • Independent Bits Engine 
  • Shuffle Order Engine
gibi sınıflar var.

Hiç yorum yok:

Yorum Gönder