Primeira vez aqui? Seja bem vindo e cheque o FAQ!
x

Como são gerados os números aleatórios?

+1 voto
16 visitas
perguntada Dez 10, 2017 em Finanças por Victor Candido (11 pontos)  

A maioria das linguagens computacionais já possui geradores de números aleatórios. Como esses números são gerados? Discute a geração desses números tendo como base o Capítulo 7 do livro Numerical Recipes in Fortran 77. Implemente pelo menos 2 exemplos de geradores de números aleatórios em python e discuta as diferenças (vantagens e desvantagens) entre eles.

Compartilhe

1 Resposta

+1 voto
respondida Dez 10, 2017 por Victor Candido (11 pontos)  
selecionada Dez 11, 2017 por danielcajueiro
 
Melhor resposta

O grande problema de gerar números aleatórios em um computador, é que ele por design é uma máquina determinística e não aleatória. Gerar sequências numéricas ou simbólicas puramente aleatórios não é bem a "praia" de um computador.

Segue um interessante trecho do livro citado na pergunta acima:

"Pode parecer perverso usa um computador, o mais precisa e
determinista de todas às máquinas concebidas pela mente humana, para
produzir números "aleatórios". Mias do que perverso, pode parecer uma
impossibilidade conceitual. Qualquer programa, afinal, produzirá
resultados que são inteiramente previsíveis, portanto não
verdadeiramente "aleatórios".

Antes dos exemplos em python, vamos discutir um algorítimo bem simples, que computadores utilizam para gerarem números randômicos. Ele utiliza uma distribuição uniforme, bastante simples para escolher números que estejam no intervalo entre 0 e 1.

Geradores lineares baseados na distribuição uniforme:

A maioria dos computadores já possuem um sistema linear de geração
de números aleatórios. O próprio Python, como veremos nos exemplos práticos, tem a sua função random. Bastante simples.
A ideia desses algoritmos é utilizar de algum método linear para gerar uma sequência de números aleatórios.

A maioria dos algoritmos embutidos em sistemas computacionais são do tipo linear congruential generators.

Algoritmos deste tipo geram uma sequência de números inteiros \(I_{1},I_{2},I_{3},...,\)
eles estão no intervalo entre \(0\) e \(m-1\) (um número grande o suficiente) pela
seguinte relação recursiva:

\(I_{j+1}=aI_{j}+c\)

Onde \(m\) é chamado de módulo, e \(a\) e \(c\) são inteiros positivos
chamados de multiplicador e incremento, respectivamente. A recorrência
dada pela igualdade acima vai se repetir, eventualmente, em um período
não maior que \(m\). Se \(m\) e \(c\) são escolhidos da maneira correta,
então o maior tamanho do intervalo será entre \(0\) e \(m-1\).

Precisamos, porém escolher um número arbitrário de onde o algoritmo irá iniciar
a sequência, ou seja, precisamos de um \(I_{0}\), de a sequência irá se iniciar. O número real entre \(0\) e \(1\), que é retornado pelo algoritmo, geralmente \(I_{j+1}/m\) que é estritamente menor que \(1\).

Mas ocasionalmente (quando \(m=0\)) o algoritmo usa \(I_{j+1}\) para gerar \(I_{j+2}\) e assim por diante...

Esse tipo de algoritmo tem como vantagem a velocidade, requer pouco esforço computacional, precisando de poucas operações para gerar uma sequência de números aleatórios. Mas sua grande desvantagem é que ele não é livre de correlações sequenciais ou repetições.

Conforme um especialista da IBM disse sobre uma rotina linear de geração de números que estava embutida em um dos famosos mainframes da marca:

"os números INDIVIDUALMENTE são aleatórios, mas eu não garanto que uma sequência deles será"

Exemplos em Python

O python usa o algorítimo Mersenne Twister que é um pseudo-gerador de números aleatórios.

Pseudogeradores recebem este nome pois ele geram sequências que possuem propriedades bastante próximas daquelas realmente aleatórias. Elas não são verdadeiramente aleatórias, pois como vimos na discussão acima, a sequência precisa de um valor inicial. Apesar dos defeitos, é um método rápido e com baixo custo computacional.

Segundo John Von Neuman:

Qualquer um que considere métodos aritméticos para produzir dígitos randômicos estará com certeza pecando.

Retornando ao algorítimo Mersenne Twister, ele é baseado em um número primo do tipo Mersenne:

\(2^{-19937}-1\)

Finalmente alguns códigos bem simples em Python:

Podemos no Python simplesmente pedir para que a função Random, gere um número aleatório em algum intervalo

random.randrange(0, 1500)

No caso acima pedimos no intervalo entre 0 e 1500.

O Python também gera números baseados em distribuições estatísticas conhecidas, como a normal, basta especificarmos a média e a variância. No caso abaixo com média 50 e variância 200.

random.normalvariate(50,200)

Também podemos fazer usando a distribuição Log-normal com média zero e variância 1.

random.lognormvariate(0,1)

Apesar de não ser o foco da discussão desta matéria, números gerados pela função Random do python nunca devem ser usados para fins de criptografia. Principalmente quando gerados por distribuições estatísticas conhecidas. E como já dito, são número gerados de forma pseudo-aleatórias.

Curiosidade: Como gerar números verdadeiramente aleatórios?

Existe uma empresa de criptografia americana, que filma luminárias de plasma como as figura abaixo:

A imagem será apresentada aqui.

Existe um algoritmo que captura o movimento das partículas e gera sequências a partir desse movimento, que se acredita que seja puramente estocástico. O interessante é o processo gerador dos números é físico e não gerado por um algoritmo.

...