Я переделал все вышеперечисленное, около 40 других страниц с c ++ в нем, вот так, и посмотрел видео от Stephan T. Lavavej «STL»,
и все еще не был уверен, как случайные числа работают в практике, поэтому я взял целое воскресенье, чтобы выяснить, что это такое и как оно работает и может быть использовано.
По моему мнению, STL прав насчет «не использовать srand больше», и он хорошо объяснил это в видео 2 . Он также рекомендует использовать:
а) void random_device_uniform()
- для зашифрованной генерации, но медленнее (из моего примера)
б) примеры с mt19937
- быстрее, возможность создавать семена, не зашифрованы
Я вытащил все заявленные книги на c ++ 11, к которым у меня есть доступ, и обнаружил, что немецкие авторы, такие как Breymann (2015), до сих пор используют клон
srand( time( 0 ) );
srand( static_cast<unsigned int>(time(nullptr))); or
srand( static_cast<unsigned int>(time(NULL))); or
просто <random>
вместо <time> and <cstdlib>
#includes - так что будьте осторожны, изучая только одну книгу :).
Значение - это не должно использоваться с c ++ 11, потому что:
Программы часто нуждаются в источнике случайных чисел. До нового стандарта и C, и C ++ полагались на простую библиотечную функцию C с именем rand. Эта функция создает псевдослучайные целые числа, которые равномерно распределены в диапазоне от 0 до системно-зависимого максимального значения, которое составляет не менее 32767. Функция rand имеет несколько проблем: многим, если не большинству программ, нужны случайные числа в другом диапазоне от один произведенный рандом. Некоторые приложения требуют случайных чисел с плавающей точкой. Некоторым программам нужны числа, отражающие неравномерное распределение. Программисты часто вводят неслучайность, когда пытаются преобразовать диапазон, тип или распределение чисел, сгенерированных rand. (цитата из учебника Lippmans C ++, пятое издание 2012 г.)
В конце концов, я нашел лучшее объяснение из 20 книг Бьярна Страуструпса, более новых - и он должен знать свои вещи - в «Путешествии по C ++ 2019», «Принципы и практика программирования с использованием C ++ 2016» и «Язык программирования C ++, 4-е издание». 2014 », а также некоторые примеры из« Учебника по Липпману C ++, пятое издание 2012 »:
И это действительно просто, потому что генератор случайных чисел состоит из двух частей:
(1) механизм, который генерирует последовательность случайных или псевдослучайных значений. (2) распределение, которое отображает эти значения в математическое распределение в диапазоне.
Несмотря на мнение парня из Microsoft STL, Бьярн Страуструпс пишет:
В стандартной библиотеке предусмотрены механизмы и распределения случайных чисел (§ 24.7). По умолчанию используется default_random_engine, который выбран для широкого применения и низкой стоимости.
void die_roll()
Пример от Бьярна Stroustrups - хорошая идея генерации двигатель и распределение с using
(более боем , что здесь) .
Чтобы иметь возможность на практике использовать генераторы случайных чисел, предоставляемые стандартной библиотекой, приведем <random>
здесь некоторый исполняемый код с различными примерами, сведенными к минимуму необходимости, который, как мы надеемся, сэкономит вам время и деньги:
#include <random> //random engine, random distribution
#include <iostream> //cout
#include <functional> //to use bind
using namespace std;
void space() //for visibility reasons if you execute the stuff
{
cout << "\n" << endl;
for (int i = 0; i < 20; ++i)
cout << "###";
cout << "\n" << endl;
}
void uniform_default()
{
// uniformly distributed from 0 to 6 inclusive
uniform_int_distribution<size_t> u (0, 6);
default_random_engine e; // generates unsigned random integers
for (size_t i = 0; i < 10; ++i)
// u uses e as a source of numbers
// each call returns a uniformly distributed value in the specified range
cout << u(e) << " ";
}
void random_device_uniform()
{
space();
cout << "random device & uniform_int_distribution" << endl;
random_device engn;
uniform_int_distribution<size_t> dist(1, 6);
for (int i=0; i<10; ++i)
cout << dist(engn) << ' ';
}
void die_roll()
{
space();
cout << "default_random_engine and Uniform_int_distribution" << endl;
using my_engine = default_random_engine;
using my_distribution = uniform_int_distribution<size_t>;
my_engine rd {};
my_distribution one_to_six {1, 6};
auto die = bind(one_to_six,rd); // the default engine for (int i = 0; i<10; ++i)
for (int i = 0; i <10; ++i)
cout << die() << ' ';
}
void uniform_default_int()
{
space();
cout << "uniform default int" << endl;
default_random_engine engn;
uniform_int_distribution<size_t> dist(1, 6);
for (int i = 0; i<10; ++i)
cout << dist(engn) << ' ';
}
void mersenne_twister_engine_seed()
{
space();
cout << "mersenne twister engine with seed 1234" << endl;
//mt19937 dist (1234); //for 32 bit systems
mt19937_64 dist (1234); //for 64 bit systems
for (int i = 0; i<10; ++i)
cout << dist() << ' ';
}
void random_seed_mt19937_2()
{
space();
cout << "mersenne twister split up in two with seed 1234" << endl;
mt19937 dist(1234);
mt19937 engn(dist);
for (int i = 0; i < 10; ++i)
cout << dist() << ' ';
cout << endl;
for (int j = 0; j < 10; ++j)
cout << engn() << ' ';
}
int main()
{
uniform_default();
random_device_uniform();
die_roll();
random_device_uniform();
mersenne_twister_engine_seed();
random_seed_mt19937_2();
return 0;
}
Я думаю, что все это складывается, и, как я уже сказал, мне потребовалось много времени для чтения и времени, чтобы перенести это на эти примеры - если у вас есть дополнительные сведения о генерации чисел, я буду рад услышать об этом в личку или в разделе комментариев. и добавит его при необходимости или отредактирует этот пост. Bool