En la documentación se dice que existe la posibilidad de que uniform(0,1)
pueda generar los valores 0
y 1
.
He corrido uniform(0, 1)
10000 veces, pero nunca produjo cero. Incluso en el caso de uniform(0, 0.001)
.
random.uniform(0,1)
Alguna vez puede generar 0
o 1
?
python
random
uniform-distribution
Venkatesh Gandi
fuente
fuente
X ~ U(0,1)
, entoncesP(X=x)
es casi seguro 0, para todos los valores de x. (Esto se debe a que hay infinitos valores posibles en el intervalo). Si está buscando exactamente 0 o 1, debe usar una función diferente, por ejemplorandom.choice
random.uniform
?Math.random()
funciona en JavaScript, por ejemplo).random.uniform(0, 1)
Respuestas:
uniform(0, 1)
puede producir0
, pero nunca producirá1
.La documentación le dice que el punto final
b
podría incluirse en los valores producidos:Entonces
uniform(0, 1)
, para , la fórmula0 + (1-0) * random()
, simplificada a1 * random()
, tendría que ser capaz de producir1
exactamente. Eso solo sucedería sirandom.random()
es 1.0exactly. However,
random ()*never* produces
1.0`.Citando la
random.random()
documentación :La notación
[..., ...)
significa que el primer valor es parte de todos los valores posibles, pero el segundo no lo es.random.random()
como máximo producirá valores muy cercanos a1.0
. Elfloat
tipo de Python es un valor de coma flotante base64 IEEE 754 , que codifica varias fracciones binarias (1/2, 1/4, 1/5, etc.) que conforman el valor, y el valor querandom.random()
produce es simplemente la suma de un selección aleatoria de esas 53 fracciones de este tipo2 ** -1
( desde 1/2) hasta2 ** -53
(1/9007199254740992).Sin embargo, debido a que puede producir valores muy cerca
1.0
, junto con los errores de redondeo que se producen cuando se multiplican flotante nubmers de puntos, se puede producirb
para algunos valores dea
yb
. Pero0
y1
no están entre esos valores.Tenga en cuenta que
random.random()
puede producir 0.0, pora
lo que siempre se incluye en los valores posibles pararandom.uniform()
(a + (b - a) * 0 == a
). Debido a que existen2 ** 53
diferentes valores querandom.random()
pueden producir (todas las combinaciones posibles de esas 53 fracciones binarias), solo hay una2 ** 53
posibilidad de 1 pulg.Entonces el valor más alto posible que
random.random()
puede producir es1 - (2 ** -53)
; simplemente elija un valor lo suficientemente pequeño como parab - a
permitir que se redondee cuando se multiplica porrandom.random()
valores más altos. Cuanto más pequeñob - a
es, mayores son las posibilidades de que eso suceda:Si aciertas
b = 0.0
, entonces hemos dividido 1023 veces, el valor anterior significa que tuvimos suerte después de 1019 divisiones. El valor más alto que encontré hasta ahora (ejecutando la función anterior en un bucle conmax()
) es8.095e-320
(1008 divisiones), pero probablemente haya valores más altos. Todo es un juego de azar. :-)También puede suceder si no hay muchos pasos discretos entre
a
yb
, como cuandoa
yb
tienen un alto exponente y, por lo tanto, puede parecer muy diferente. Los valores de coma flotante siguen siendo solo aproximaciones, y el número de valores que pueden codificar es finito. Por ejemplo, solo hay 1 fracción binaria de diferencia entresys.float_info.max
ysys.float_info.max - (2 ** 970)
, por lo que hay una probabilidad de 50-50 querandom.uniform(sys.float_info.max - (2 ** 970), sys.float_info.max)
producesys.float_info.max
:fuente
"Varias veces" no es suficiente. 10,000 no es suficiente.
random.uniform
elige entre 2 ^ 53 (9,007,199,254,740,992) valores diferentes. Estás interesado en dos de ellos. Como tal, debe esperar generar varios billones de valores aleatorios antes de obtener un valor que sea exactamente 0 o 1. Por lo tanto, es posible, pero es muy probable que nunca lo observe.fuente
uniform(0, 1)
es imposible producir1
como resultado. Esto se debe a que la función simplemente se define comodef uniform(a, b): return a + (b - a) * random()
yrandom()
nunca puede producir1.0
.Puede intentar generar un ciclo que cuente la cantidad de iteraciones necesarias para que se muestre un 0 exacto (no).
Además, como dijo Hobbs, la cantidad de valores que se están
uniformly
muestreando son 9,007,199,254,740,992. Lo que significa que la probabilidad de ver un 0 es exactamente 1 / 9,007,199,254,740,992. Lo que en términos generales y redondeando significa que necesitará en promedio 10 billones de muestras para encontrar un 0. Por supuesto, puede encontrarlo en sus primeros 10 intentos, o nunca.El muestreo de 1 es imposible ya que el intervalo definido para los valores se cierra con un paréntesis, por lo tanto, no incluye 1.
fuente
Por supuesto. Ya estabas en el camino correcto al intentarlo
uniform(0, 0.001)
. Solo sigue restringiendo los límites lo suficiente como para que suceda antes.fuente