Припустимо, ви хочете використовувати засоби C ++ <random>
у практичній програмі (для деякого визначення поняття "практичний" - обмеження тут є частиною цього питання). У вас приблизно такий код:
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);
}
Моє запитання, який тип слід використовувати ENGINE
?
Я завжди говорив,
std::mt19937
тому що це було швидко вводити і розпізнавати імена. Але в наші дні здається, що всі говорять про те, що Mersenne Twister дуже важка і не кеш-пам'ять і навіть не здає всіх статистичних тестів, які роблять інші.Я хотів би сказати,
std::default_random_engine
тому що це очевидний "дефолт". Але я не знаю, чи варіюється вона від платформи до платформи, і я не знаю, чи є це статистично корисним.Оскільки в наші дні всі працюють на 64-бітній платформі, чи варто нам принаймні використовувати
std::mt19937_64
більшеstd::mt19937
?Я хотів би сказати
pcg64
абоxoroshiro128
тому, що вони здаються шанованими і легкими, але їх взагалі немає<random>
.Я нічого не знаю
minstd_rand
,minstd_rand0
,ranlux24
,knuth_b
звичайно , вони повинні бути добре для чого - то - і т.д.?
Очевидно, що тут є деякі конкуруючі обмеження.
Міцність двигуна. (
<random>
не має криптографічно сильних PRNG, але все ж деякі стандартизовані "слабкіші", ніж інші, правда?)sizeof
двигун.Швидкість його
operator()
.Простота висіву насіння.
mt19937
сумно важко висівати належним чином, оскільки у нього стільки стану для ініціалізації.Переносимість між постачальниками бібліотек. Якщо один постачальник
foo_engine
виробляє різні номери від інших постачальниківfoo_engine
, це не добре для деяких програм. (Сподіваємось, це не виключає нічого, крім можливоdefault_random_engine
.)
Зваживши всі ці обмеження якнайкраще, що ви скажете, це остаточна відповідь "найкраща практика перебування в межах стандартної бібліотеки"? Чи варто просто продовжувати використовувати std::mt19937
, чи що?