Diyelim ki C ++ <random>
olanaklarını pratik bir programda kullanmak istiyorsunuz ("pratik" in bazı tanımları için - buradaki kısıtlamalar bu sorunun bir parçasıdır). Kabaca şöyle bir kod var:
int main(int argc, char **argv) {
int seed = get_user_provided_seed_value(argc, argv);
if (seed == 0) seed = std::random_device()();
ENGINE g(seed); // TODO: proper seeding?
go_on_and_use(g);
}
Sorum şu, ne tür kullanmalısın ENGINE
?
Her zaman söylerdim
std::mt19937
çünkü yazmak hızlıydı ve isim tanıması vardı. Ancak bu günlerde herkes Mersenne Twister'ın çok ağır ve önbellek dostu olduğunu ve başkalarının yaptığı tüm istatistiksel testleri bile geçmediğini söylüyor.Söylemek isterim
std::default_random_engine
çünkü bu bariz "varsayılan". Ama platformdan platforma değişip değişmediğini bilmiyorum ve istatistiksel olarak iyi olup olmadığını bilmiyorum.Bugünlerde herkes 64-bit platformunda olduğundan, bunu en azından kullanarak olmalı
std::mt19937_64
üzerindestd::mt19937
?Söylemek isterim
pcg64
ya daxoroshiro128
saygın ve hafif göründüklerinden, ama hiç yoklar<random>
.Ben hakkında hiçbir şey bilmiyorum
minstd_rand
,minstd_rand0
,ranlux24
,knuth_b
mutlaka bir şey için iyi olmalıdır - vs.?
Açıkçası burada bazı rakip kısıtlamalar var.
Motor gücü. (
<random>
kriptografik olarak güçlü PRNG'leri yoktur, ancak yine de, standartlaştırılmış olanlardan bazıları diğerlerinden daha zayıftır, değil mi?)sizeof
motor.Hızı
operator()
.Ekim kolaylığı.
mt19937
başlaması için çok fazla durumu olduğu için doğru şekilde tohumlanması çok zordur.Kütüphane satıcıları arasında taşınabilirlik. Bir satıcının
foo_engine
başka bir satıcınınkinden farklı numaralar üretmesifoo_engine
, bazı uygulamalar için iyi değildir. (Umarım bu belki dışında hiçbir şeyi dışlamazdefault_random_engine
.)
Tüm bu kısıtlamaları elinizden geldiğince tartarak, nihai "standart kütüphanenin içinde kalmak için en iyi uygulama" cevabı nedir? Sadece kullanmaya devam etmeli miyim std::mt19937
yoksa ne?