Na documentação , diz-se que há uma chance de uniform(0,1)
gerar os valores 0
e 1
.
Já corri uniform(0, 1)
10000 vezes, mas nunca produziu zero. Mesmo no caso de uniform(0, 0.001)
.
Já pode random.uniform(0,1)
gerar 0
ou 1
?
python
random
uniform-distribution
Venkatesh Gandi
fonte
fonte
X ~ U(0,1)
, então,P(X=x)
é quase certamente 0, para todos os valores de x. (Isso ocorre porque existem infinitos valores possíveis no intervalo.) Se você está procurando exatamente 0 ou 1, deve usar uma função diferente - por exemplorandom.choice
random.uniform
?Math.random()
funciona em JavaScript, por exemplo).random.uniform(0, 1)
retornar a 0 na primeira chamadaRespostas:
uniform(0, 1)
pode produzir0
, mas nunca produzirá1
.A documentação informa que o terminal
b
pode ser incluído nos valores produzidos:Portanto
uniform(0, 1)
, a fórmula0 + (1-0) * random()
, simplificada para1 * random()
, teria que ser capaz de produzir1
exatamente. Isso só aconteceria serandom.random()
fosse 1.0exactly. However,
random ()*never* produces
1.0`.Citando a
random.random()
documentação :A notação
[..., ...)
significa que o primeiro valor faz parte de todos os valores possíveis, mas o segundo não.random.random()
vontade na maioria dos valores produzem muito perto de1.0
. Ofloat
tipo de Python é um valor de ponto flutuante IEEE 754 base64 , que codifica várias frações binárias (1/2, 1/4, 1/5 etc.) que compõem o valor, e o valorrandom.random()
produzido é simplesmente a soma de uma seleção aleatória dessas 53 frações de2 ** -1
(1/2) a2 ** -53
(1/9007199254740992).No entanto, como ele pode produzir valores muito próximos
1.0
, juntamente com os erros de arredondamento que ocorrem quando você multiplica os nubmers de ponto flutuante, é possível produzirb
para alguns valores dea
eb
. Mas0
e1
não estão entre esses valores.Observe que
random.random()
pode produzir 0,0, portanto,a
é sempre incluído nos valores possíveis pararandom.uniform()
(a + (b - a) * 0 == a
). Como existem2 ** 53
valores diferentes querandom.random()
podem produzir (todas as combinações possíveis dessas 53 frações binárias), existe apenas uma2 ** 53
chance de 1 em (então 1 em 9007199254740992) de que isso aconteça.Portanto, o maior valor possível que
random.random()
pode produzir é1 - (2 ** -53)
; basta escolher um valor pequeno o suficiente parab - a
permitir o arredondamento quando multiplicado porrandom.random()
valores mais altos. Quanto menorb - a
, maiores as chances de isso acontecer:Se você acertar
b = 0.0
, dividimos 1023 vezes, o valor acima significa que tivemos sorte após 1019 divisões. O valor mais alto que encontrei até agora (executando a função acima em um loop commax()
) é8.095e-320
(1008 divisões), mas provavelmente existem valores mais altos. É tudo um jogo de azar. :-)Também pode acontecer se não houver muitas etapas discretas entre
a
eb
, como quandoa
eb
tiver um expoente alto e, portanto, parecer distante. Os valores de ponto flutuante ainda são apenas aproximações e o número de valores que eles podem codificar é finito. Por exemplo, há apenas 1 fração binária de diferença entresys.float_info.max
esys.float_info.max - (2 ** 970)
, portanto, há uma chance de 50-50random.uniform(sys.float_info.max - (2 ** 970), sys.float_info.max)
produzsys.float_info.max
:fonte
"Várias vezes" não é suficiente. 10.000 não é suficiente.
random.uniform
escolhe entre 2 ^ 53 (9.007.199.254.740.992) valores diferentes. Você está interessado em dois deles. Como tal, você deve gerar vários valores aleatórios de quatrilhões antes de obter um valor exatamente 0 ou 1. Portanto, é possível, mas é muito provável que você nunca o observe.fonte
uniform(0, 1)
é impossível produzir1
como resultado. Isso ocorre porque a função é simplesmente definida comodef uniform(a, b): return a + (b - a) * random()
erandom()
nunca pode produzir1.0
.Você pode tentar gerar um loop que conte a quantidade de iterações necessárias para mostrar um 0 exato (não).
Além disso, como Hobbs afirmou, a quantidade de valores
uniformly
amostrados é de 9.007.199.254.740.992. O que significa que a probabilidade de ver um 0 é exatamente 1 / 9.007.199.254.740.992. O que, em termos gerais e arredondamento, significa que você precisará, em média, de 10 quatrilhões de amostras para encontrar um 0. É claro que você pode encontrá-lo nas suas primeiras 10 tentativas, ou nunca.A amostragem de 1 é impossível, pois o intervalo definido para os valores é fechado entre parênteses, portanto, não incluindo 1.
fonte
Certo. Você já estava no caminho certo ao tentar
uniform(0, 0.001)
. Continue restringindo os limites o suficiente para que isso aconteça mais cedo.fonte