2013-04-09 19 views
5

Belirli bir aralıktan [lower, upper] rastgele tamsayılar üretmek için aşağıdaki sınıfı yazdım.Değişen aralıktan verimli bir şekilde rasgele tamsayılar üretme

class RandomInteger { 

protected: 

    std::random_device randomDevice; 
    std::default_random_engine randomEngine; 
    std::uniform_int_distribution<> distribution; 

public: 

    RandomInteger(int64_t lower, int64_t upper); 

    virtual ~RandomInteger(); 

    virtual int64_t generate(); 
}; 


RandomInteger::RandomInteger(int64_t lower, int64_t upper) : randomEngine(this->randomDevice()), distribution(lower, upper) { 
} 

RandomInteger::~RandomInteger() { 
    // TODO Auto-generated destructor stub 
} 

int64_t RandomInteger::generate() { 
    int64_t i = this->distribution(this->randomEngine); 
    return i; 
} 

aralık yapılır generate aynı ve çoklu aramaları kalırsa bu tamamdır. Ancak, şimdi benim kullanım durumum sürekli değişen bir aralıktan tamsayılar üretiyor (üst sınır her seferinde artar).

Her şeyden önce, bunun hızlı olması gerekir. Bu kriptografi ile hiçbir ilgisi yoktur, bu yüzden çok rasgele sayılar iyidir (ve std::random_device muhtemelen gerekli değildir). Mümkünse C stilinden kaçınmak ve modern C++ 11 stilini kullanmak isterim.

Bunu verimli bir şekilde yapmanızı önerebilir misiniz?

+2

Dağıtımın değiştirilmesi yeterince verimli değil mi? "uniform_int_distribution" çok zayıf bir sarıcıdır, önemli bir ek yük olmamalıdır. Ayrıca, sınıfınızdaki fonksiyonlar neden sanal? –

+0

@KonradRudolph Sanal olmalarına gerek yok. Buradaki önemli hızlanmalarda onlara gerçekçi olmayan sonuç verir mi? Sanal yöntem çağrıları için ek yükün çok düşük olduğunu öğrendim. Bu garip bir durum: C++ bir OOP dili olduğunu iddia ediyor. OOP, kodunuzu gelecekte genişletilebilir ve yeniden kullanılabilir hale getirmekle ilgilidir. Bununla birlikte, birçok C++ programcısı, şu anda açıkça ihtiyaç duyulmadıkça, diğerlerini OOP'u devre dışı bırakmalarını (yani metotları gayri gerçek) yapmalarını tavsiye etmektedir. – clstaudt

+0

@KonradRudolph, "dağıtımı değiştirmek" yeni bir 'std :: uniform_int_distribution'ı farklı parametrelerle örneklemek anlamına mı geliyor? – clstaudt

cevap

2

Kullanım kabul uniform_int_distribution::operator() aşırı yük bir const param_type &.

int64_t RandomInteger::generate(int64_t lower, int64_t upper) { 
    int64_t i = this->distribution(this->randomEngine, 
     std::uniform_int_distribution<int64_t>{lower, upper}.param()); 
    return i; 
} 

(sen onun param ayarı ilgilenmiyor gibi distribution değer-başlatmak gerektiğini unutmayın Ayrıca distributionint64_t ile şablon edilmelidir, int.)

uniform_int_distribution herhangi bir durumu koruyorsa, bu verimli bir şekilde kullanacaktır. Gerçekte, çoğu uygulama uniform_int_distribution, herhangi bir durumu koruyamıyor; bakınız örn. libstdC++ random.tcc: http://gcc.gnu.org/onlinedocs/gcc-4.6.0/libstdc++/api/a01001_source.html#l00832

İlgili konular