I vermelho todo o material acima, cerca de 40 outras páginas com C ++ no-lo como este e assistiu ao vídeo do Stephan T. Lavavej "STL"
e ainda não tinha certeza de como aleatório números obras na práxis por isso, tomei um domingo inteiro para descobrir do que se trata e como funciona e pode ser usado.
Na minha opinião, a STL está certa sobre "não usar mais o srand" e ele explicou bem no vídeo 2 . Ele também recomenda usar:
a) void random_device_uniform()
- para geração criptografada, mas mais lenta (do meu exemplo)
b) os exemplos com mt19937
- mais rápido, capacidade de criar sementes, não criptografadas
Peguei todos os livros c ++ 11 reivindicados aos quais tenho acesso e descobri que autores alemães como Breymann (2015) ainda usam um clone de
srand( time( 0 ) );
srand( static_cast<unsigned int>(time(nullptr))); or
srand( static_cast<unsigned int>(time(NULL))); or
apenas em <random>
vez de <time> and <cstdlib>
#includings - tenha cuidado para aprender apenas com um livro :).
Significado - que não deve ser usado desde c ++ 11 porque:
Os programas geralmente precisam de uma fonte de números aleatórios. Antes do novo padrão, C e C ++ contavam com uma função simples da biblioteca C chamada rand. Essa função produz números inteiros pseudo-aleatórios que são distribuídos uniformemente no intervalo de 0 a um valor máximo dependente do sistema que é pelo menos 32767. A função rand tem vários problemas: Muitos, se não a maioria, programas precisam de números aleatórios em um intervalo diferente do um produzido pela rand. Alguns aplicativos exigem números aleatórios de ponto flutuante. Alguns programas precisam de números que reflitam uma distribuição não uniforme. Os programadores geralmente introduzem a não aleatoriedade quando tentam transformar o intervalo, o tipo ou a distribuição dos números gerados pelo rand. (citação de Lippmans C ++ primer quinta edição de 2012)
Finalmente encontrei a melhor explicação de 20 livros nos livros mais recentes de Bjarne Stroustrups - e ele deve saber tudo - em "Um tour pelo C ++ 2019", "Princípios e práticas de programação usando C ++ 2016" e "Linguagem de programação C ++ 4ª edição 2014 "e também alguns exemplos em" Lippmans C ++ primer quinta edição 2012 ":
E é realmente simples, porque um gerador de números aleatórios consiste em duas partes:
(1) um mecanismo que produz uma sequência de valores aleatórios ou pseudo-aleatórios. (2) uma distribuição que mapeia esses valores em uma distribuição matemática em um intervalo.
Apesar da opinião do cara da Microsofts STL, Bjarne Stroustrups escreve:
Em, a biblioteca padrão fornece mecanismos e distribuições de números aleatórios (§24.7). Por padrão, use o default_random_engine, escolhido para ampla aplicabilidade e baixo custo.
O void die_roll()
exemplo é de Bjarne Stroustrups - boa ideia gerando mecanismo e distribuição com using
(mais sobre isso aqui) .
Para poder fazer uso prático dos geradores de números aleatórios fornecidos pela biblioteca padrão <random>
aqui, alguns códigos executáveis com exemplos diferentes são reduzidos ao mínimo necessário, que esperamos ter tempo e dinheiro seguros para vocês:
#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;
}
Eu acho que isso acrescenta tudo e, como eu disse, levei um monte de leitura e tempo para dedicar a esses exemplos - se você tiver mais informações sobre geração de números, fico feliz em saber sobre isso via pm ou na seção de comentários e irá adicioná-lo, se necessário, ou editar esta postagem. Bool