Suponha que temos um gerador aleatório que gera números no intervalo com distribuição uniforme e precisamos gerar números aleatórios no intervalo com distribuição uniforme.[ 0 .. N - 1 ]
Suponha que e não divida uniformemente ; para obter uma distribuição verdadeiramente uniforme , podemos usar o método de amostragem por rejeição :N R
- se é o maior número inteiro, de modo quek N < R
- escolha um número aleatório em[ 0 .. R - 1 ]
- se então gera r \ mod N , caso contrário, continue tentando com outros números aleatórios r ', r ", ... até que a condição seja atendida
A amostragem por rejeição é a única maneira de obter uma distribuição discreta verdadeiramente uniforme?
Se a resposta for sim, por quê?
Nota: se a idéia é a mesma: gere um número aleatório em , por exemplo que é um número aleatório no intervalo
Respostas:
Sim e não, dependendo do que você quer dizer com "o único caminho". Sim, na medida em que não há um método garantido para terminar, o melhor que você pode fazer (para valores genéricos de e ) é um algoritmo que termina com probabilidade 1. Não, na medida em que você pode fazer com que o “desperdício” seja pequeno Como você quiser.RN R
Por que a rescisão garantida é impossível em geral
Suponha que você tenha um mecanismo de computação determinístico (uma máquina de Turing ou o que flutua no seu barco), além de um oráculo que gera elementos aleatórios do conjunto de elementos . Seu objetivo é gerar um elemento do conjunto de elementos . A saída do seu mecanismo depende apenas da sequência de valores retornados pelo oráculo; é uma função dessa sequência potencialmente infinita .[ 0 .. R - 1 ] N [ 0 , N - 1 ] f ( r 0 , r 1 , r 2 , … )R [0..R−1] N [0,N−1] f (r0,r1,r2,…)
Suponha que seu motor chame o oráculo no máximo vezes. Pode haver vestígios pelos quais o oráculo é chamado menos de vezes; nesse caso, chamar o oracle vezes extras para que ele seja sempre chamado exatamente times não altera a saída. Portanto, sem perda de generalidade, assumimos que o oráculo é chamado exatamente vezes. Então a probabilidade do resultado é o número de seqüências tal forma que . Como o oráculo é um gerador aleatório uniforme, cada sequência é equiprobável e tem a probabilidade . Portanto, a probabilidade de cada resultado é da formam m m x ( r 0 , … , r m - 1 ) f ( r 0 , … , r m - 1 ) = x 1 / R m A / R m Am m m m x (r0,…,rm−1) f(r0,…,rm−1)=x 1/Rm A/Rm onde é um número inteiro entre e .A R m0 Rm
Se divide por alguns , você pode gerar uma distribuição uniforme sobre elementos chamando o gerador aleatório vezes (isso é deixado como um exercício para o leitor). Caso contrário, isso é impossível: não há nenhuma maneira de obter um resultado com probabilidade . Observe que a condição é equivalente a dizer que todos os fatores primos de também são fatores de (isso é mais permissivo do que o que você escreveu em sua pergunta; por exemplo, você pode escolher um elemento aleatório entre 4 com uma equação de 6 lados morra, mesmo que 4 não divida 6).R m m N m 1 / N N RN Rm m N m 1/N N R
Reduzindo o desperdício
Na sua estratégia, quando , você não precisa redesenhar imediatamente. Intuitivamente, resta um pouco de entropia em que você pode manter na mistura.[ kr≥kN [kN..R−1]
Suponha por um momento que você vai de fato manter a geração de números aleatórios abaixo para sempre, e você gera deles de cada vez, fazendo empates. Se você fizer uma amostragem direta de rejeição nessa geração agrupada, o desperdício sobre será , ou seja, o restante dividido pelo número de empates. Isso pode ser tão pequeno quanto . Quando e são coprime, você pode reduzir o desperdício arbitrariamente pequeno escolhendo valores suficientemente grandes de . Para valores gerais de eu d d R d - kN u d d Rd−kNud RdmodNu R N d R N gcd ( R , N ) N / gcd ( R , N )gcd(R,N) R N d R N , o cálculo é mais complicado porque é necessário levar em consideração a geração de e separadamente, mas novamente você pode reduzir o desperdício arbitrariamente pequeno com grupos grandes o suficiente.gcd(R,N) N/gcd(R,N)
Na prática, mesmo com números aleatórios relativamente ineficientes (por exemplo, em criptografia), raramente vale a pena fazer algo além de amostragem simples de rejeição, a menos que seja pequeno. Por exemplo, na criptografia, onde é tipicamente uma potência de 2 e é tipicamente centenas ou milhares de bits, a geração uniforme de números aleatórios geralmente procede por amostragem direta por rejeição no intervalo desejado.R NN R N
fonte
O teorema da codificação de origem de Shannon mostra que, no sentido exato, você precisa de samples (em média) do tipo para gerar um número aleatório do tipo . Mais precisamente, Shannon fornece um algoritmo (ineficiente) que, com amostras do primeiro tipo, gera amostras do segundo tipo, com alta probabilidade. Ele também mostra que é impossível enviar amostras com alta probabilidade.[ 0 , … , R - 1 ] [ 0 , … , N - 1 ] m m ( log N / log R - ϵ ) m ( log N / log R + ϵ )logN/logR [0,…,R−1] [0,…,N−1] m m(logN/logR−ϵ) m(logN/logR+ϵ)
O teorema de Shannon também funciona no caso mais geral de uma distribuição de entrada assimétrica (e provavelmente também uma distribuição de saída assimétrica). Nesse caso, você precisa substituir o logaritmo pela entropia. Enquanto o algoritmo dado pelo teorema é definido aleatoriamente, em alguns casos é possível derandomizá-lo (à custa de um desempenho um pouco pior).
fonte
Na verdade, não, a amostragem por rejeição está longe de ser a única maneira de proceder. Infelizmente, considerando que os computadores armazenam todas as informações como bits e, portanto, só podem manipular bits aleatórios de informações, qualquer algoritmo para desenhar uma variável aleatória uniforme do intervalo será infinito, se o desenvolvimento da base binária de for infinito.NN N
Esse teorema é um resultado clássico de Knuth e Yao (1976), que desenvolveu a estrutura das árvores DDG (árvores geradoras de distribuição discreta).
Os métodos expostos por Gilles são o tipo típico de coisa que foi feita para mitigar o desperdício causado pela rejeição, mas é claro que se é possível gerar seguindo as árvores de Knuth e Yao, é muito, muito mais eficiente - em média 96% dos bits aleatórios são salvos.
Eu forneci mais informações sobre isso no seguinte post da CStheory .
fonte