Припустимо, ви хочете використовувати засоби 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, чи що?