Załóżmy, że chcesz korzystać z narzędzi C ++ <random>
w praktycznym programie (dla pewnej definicji „praktyczny” - ograniczenia tutaj są swego rodzaju częścią tego pytania). Masz mniej więcej taki kod:
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);
}
Moje pytanie brzmi: do jakiego rodzaju należy używać ENGINE
?
Zawsze mówiłem,
std::mt19937
bo szybko pisałem i rozpoznawałem nazwy. Ale w dzisiejszych czasach wydaje się, że wszyscy mówią, że Mersenne Twister jest bardzo ciężki i nieprzyjazny dla pamięci podręcznej i nie przechodzi nawet wszystkich testów statystycznych, które przeprowadzają inni.Chciałbym powiedzieć,
std::default_random_engine
ponieważ to oczywiste „domyślne”. Ale nie wiem, czy różni się w zależności od platformy i nie wiem, czy jest to statystycznie dobre.Ponieważ każdy jest na platformie 64-bitowej te dni, powinniśmy być przynajmniej przy użyciu
std::mt19937_64
ponadstd::mt19937
?Chciałbym powiedzieć
pcg64
lubxoroshiro128
dlatego, że wydają się szanowani i lekcy, ale w ogóle ich nie ma<random>
.Nie wiem nic na temat
minstd_rand
,minstd_rand0
,ranlux24
,knuth_b
na pewno muszą być dobre dla czegoś -, itd.?
Oczywiście istnieją tutaj pewne konkurencyjne ograniczenia.
Wytrzymałość silnika. (
<random>
nie ma silnie kryptograficznie PRNG, ale niektóre ze standardowych są „słabsze” niż inne, prawda?)sizeof
silnik.Szybkość jego
operator()
.Łatwość siewu.
mt19937
jest bardzo trudne do prawidłowego zaszczepienia, ponieważ ma tyle stanu do zainicjowania.Przenośność między dostawcami bibliotek. Jeśli jeden sprzedawca
foo_engine
wytwarza inne numery od innegofoo_engine
, nie jest to dobre dla niektórych aplikacji. (Mam nadzieję, że nie wyklucza to niczego opróczdefault_random_engine
.)
Biorąc pod uwagę wszystkie te ograniczenia najlepiej, jak potrafisz, co powiedziałbyś, że jest najlepszą odpowiedzią na „pozostawanie w standardowej bibliotece”? Czy powinienem po prostu dalej używać std::mt19937
, czy co?