Dans la documentation, il est dit qu'il existe une chance qui uniform(0,1)
peut générer les valeurs 0
et 1
.
J'ai couru uniform(0, 1)
10 000 fois, mais cela n'a jamais produit zéro. Même dans le cas de uniform(0, 0.001)
.
Peut random.uniform(0,1)
jamais générer 0
ou 1
?
python
random
uniform-distribution
Venkatesh Gandi
la source
la source
X ~ U(0,1)
, alors leP(X=x)
est presque sûrement 0, pour toutes les valeurs de x. (C'est parce qu'il y a une infinité de valeurs possibles dans l'intervalle.) Si vous recherchez exactement 0 ou 1, vous devez utiliser une fonction différente - par exemplerandom.choice
random.uniform
?Math.random()
fonctionne en JavaScript, par exemple).random.uniform(0, 1)
Réponses:
uniform(0, 1)
peut produire0
, mais il ne produira jamais1
.La documentation vous indique que le noeud final
b
peut être inclus dans les valeurs produites:Donc, pour
uniform(0, 1)
, la formule0 + (1-0) * random()
, simplifiée en1 * random()
, devrait être capable de produire1
exactement. Cela ne se produirait que sirandom.random()
1.0exactly. However,
random ()*never* produces
1.0`.Citant la
random.random()
documentation :La notation
[..., ...)
signifie que la première valeur fait partie de toutes les valeurs possibles, mais pas la seconde.random.random()
produira tout au plus des valeurs très proches de1.0
. Lefloat
type de Python est une valeur à virgule flottante base64 IEEE 754 , qui code un certain nombre de fractions binaires (1/2, 1/4, 1/5, etc.) qui composent la valeur, et la valeurrandom.random()
produite est simplement la somme d'un sélection aléatoire de ces 53 fractions de2 ** -1
(1/2) à2 ** -53
(1/9007199254740992).Cependant, comme il peut produire des valeurs très proches de
1.0
, ainsi que des erreurs d'arrondi qui se produisent lorsque vous multipliez des nombres à virgule flottante, vous pouvez produireb
pour certaines valeurs dea
etb
. Mais0
et1
ne font pas partie de ces valeurs.Notez que
random.random()
peut produire 0,0, ila
est donc toujours inclus dans les valeurs possibles pourrandom.uniform()
(a + (b - a) * 0 == a
). Parce qu'il existe2 ** 53
différentes valeurs quirandom.random()
peuvent produire (toutes les combinaisons possibles de ces 53 fractions binaires), il n'y a qu'une2 ** 53
chance sur 1 (donc 1 sur 9007199254740992) que cela se produise.Donc, la valeur la plus élevée possible qui
random.random()
peut produire est1 - (2 ** -53)
; il suffit de choisir une valeur suffisamment petite pourb - a
permettre l'arrondi au coup d'envoi lorsqu'il est multiplié par desrandom.random()
valeurs plus élevées. Plus la tailleb - a
est petite , plus les chances que cela se produise sont grandes:Si vous frappez
b = 0.0
, alors nous avons divisé 1023 fois, la valeur ci-dessus signifie que nous avons eu de la chance après 1019 divisions. La valeur la plus élevée que j'ai trouvée jusqu'à présent (en exécutant la fonction ci-dessus en boucle avecmax()
) est8.095e-320
(1008 divisions), mais il y a probablement des valeurs plus élevées. C'est tout un jeu de hasard. :-)Cela peut également se produire s'il n'y a pas beaucoup d'étapes discrètes entre
a
etb
, comme quanda
etb
ont un exposant élevé et peuvent donc sembler éloignées. Les valeurs en virgule flottante ne sont encore que des approximations et le nombre de valeurs qu'elles peuvent coder est fini. Par exemple, il n'y a qu'une seule fraction binaire de différence entresys.float_info.max
etsys.float_info.max - (2 ** 970)
, il y a donc 50 à 50 chances derandom.uniform(sys.float_info.max - (2 ** 970), sys.float_info.max)
produiresys.float_info.max
:la source
"Plusieurs fois" ne suffit pas. 10 000 n'est pas suffisant.
random.uniform
choisit parmi 2 ^ 53 (9,007,199,254,740,992) différentes valeurs. Vous êtes intéressé par deux d'entre eux. En tant que tel, vous devez vous attendre à générer plusieurs quadrillions de valeurs aléatoires avant d'obtenir une valeur qui est exactement 0 ou 1. C'est donc possible, mais il est très probable que vous ne l'observerez jamais.la source
uniform(0, 1)
il est impossible de produire1
comme résultat. C'est parce que la fonction est simplement définie commedef uniform(a, b): return a + (b - a) * random()
etrandom()
ne peut jamais produire1.0
.Vous pouvez essayer de générer une boucle qui compte le nombre d'itérations nécessaires pour afficher un 0 exact (ne le faites pas).
En outre, comme l'a déclaré Hobbs, le montant des valeurs
uniformly
échantillonnées est de 9 007 199 254 740 992. Ce qui signifie que la probabilité de voir un 0 est exactement de 1/9 007 199 254 740 992. Ce qui en termes généraux et en arrondissant signifie que vous aurez besoin en moyenne de 10 quatrillions d'échantillons pour trouver un 0. Bien sûr, vous pourriez le trouver dans vos 10 premières tentatives, ou jamais.L'échantillonnage de 1 est impossible car l'intervalle défini pour les valeurs est fermé par une parenthèse, donc sans inclure 1.
la source
Sûr. Vous étiez déjà sur la bonne voie en essayant à la
uniform(0, 0.001)
place. Continuez à restreindre suffisamment les limites pour que cela se produise plus tôt.la source