Random.iform (0,1) hiç 0 veya 1 üretebilir mi?


9

Gelen belgelere bir şans olduğu söylenir uniform(0,1)değerleri oluşturabilir 0ve 1.

Ben yayınlandıktan uniform(0, 1)10000 defa, ama sıfır üretti olmadı. Durumunda bile uniform(0, 0.001).

Can random.uniform(0,1)Hiç üretmek 0veya 1?


3
Teorik olarak muhtemeldir, ancak pratik olarak asla olmayacaktır. Eğer Matematiksel olarak, standart tek tip rasgele değişken, 0 ile 1 arasında bir aralıkta bir değer alabilir X ~ U(0,1), o zaman P(X=x)olduğu hemen hemen kesin 0 x tüm değerleri için. (Bunun nedeni aralıkta sonsuz sayıda olası değer bulunmasıdır.) Tam olarak 0 veya 1 arıyorsanız, farklı bir işlev kullanmalısınızrandom.choice
01'de pault

1
@pault'un matematikte neredeyse çok belirgin bir anlamı vardır, bu da burada gerçekten mantıklı değildir, çünkü sürekli bir aralık değil ayrık bir dağılımımız vardır. 0 ile 1 arasında sadece sınırlı sayıda yüzer vardır.
wim

2
@pault Peki OP'nin uygulanmasını sorurken neden matematiksel olarak konuşuyorsunuz random.uniform?
wim

1
Bu dokümantasyon doğruysa, hem 0 hem de 1 üretmek için nasıl yapıldığını merak ediyorum. [0, 1) çok daha kolay olurdu ( Math.random()örneğin JavaScript'te bu şekilde çalışır).
Ry-

1
random.uniform(0, 1)İlk çağrıda 0 döndüren rastgele bir tohum göndermek için ilk kişi için 50 puan ödül
wim

Yanıtlar:


13

uniform(0, 1)üretebilir 0, ama asla üretmez 1.

Dokümantasyon son nokta olduğunu söyler b olabilir üretilen değerler dahil edilmesi:

Uç nokta değeri b, denklemdeki kayan nokta yuvarlamasına bağlı olarak aralığa dahil edilebilir veya edilmeyebilir a + (b-a) * random().

Dolayısıyla , sadeleştirilmiş uniform(0, 1)formülün tam olarak üretebilmesi gerekirdi . Bu sadece 1.0 rasgele () 1.0` olduğunda olur.0 + (1-0) * random()1 * random()1random.random()exactly. However,*never* produces

random.random()Belgelerin alıntılanması :

[0.0, 1.0) aralığındaki bir sonraki rasgele kayan nokta sayısını döndürün.

Gösterim [..., ...), ilk değerin tüm olası değerlerin bir parçası olduğu, ancak ikincisinin olmadığı anlamına gelir. random.random()En üretim değerlerinde irade çok yakındır için 1.0. Python'un floattürü, değeri oluşturan bir dizi ikili fraksiyonu (1/2, 1/4, 1/5, vb.) Kodlayan bir IEEE 754 base64 kayan nokta değeridir ve üretilen değer random.random()basitçe bir 2 ** -1(1/2) 'den 2 ** -53(1/9007199254740992)' ye kadar olan bu 53 fraksiyonun rasgele seçimi .

Çok yakın değerler üretebilir Ancak, 1.0birlikte size çarpma noktası nubmers kayan ortaya çıkan hataları yuvarlama ile, sen yapabilirsiniz üretmek biçin bazı değerleri ave b. Ancak 0ve 1bu değerler arasında değildir.

Not random.random() olabilir 0.0 üretmek, yani a, her zaman için olası değerleri dahildir random.uniform()( a + (b - a) * 0 == a). Üretebilecek 2 ** 53farklı değerler olduğundan random.random()(bu 53 ikili fraksiyonun tüm olası kombinasyonları), bunun gerçekleşmesi için sadece 1 inç 2 ** 53(yani 9007199254740992'de 1) şansı vardır.

Böylece random.random()üretebilecek en yüksek değer 1 - (2 ** -53); b - adaha yüksek random.random()değerlerle çarpıldığında yuvarlamanın devreye girmesine izin verecek kadar küçük bir değer seçmeniz yeterlidir . Ne kadar küçükse b - a, bunun gerçekleşme şansı o kadar artar:

>>> import random, sys
>>> def find_b():
...     a, b = 0, sys.float_info.epsilon
...     while random.uniform(a, b) != b:
...         b /= 2
...     else:
...         return b
...
>>> print("uniform(0, {0}) == {0}".format(find_b()))
...
uniform(0, 4e-323) == 4e-323

Eğer vurursanız b = 0.0, 1023 kez böldük, yukarıdaki değer 1019 bölümden sonra şanslı olduğumuz anlamına gelir. Şimdiye kadar bulduğum en yüksek değer (yukarıdaki işlevi bir döngüde çalıştırmak max()) 8.095e-320(1008 bölüm), ancak muhtemelen daha yüksek değerler var. Hepsi bir şans oyunu. :-)

Ayrıca aralarında birçok ayrık adımlar olup olmadığını ortaya çıkabilir ave bzaman gibi ave byüksek üs var ve şu ana kadar appart gibi görünebilir. Kayan nokta değerleri hala sadece yaklaşık değerlerdir ve kodlayabilecekleri değerlerin sayısı sonludur. Örneğin, orada arasındaki farkın sadece 1 ikili kesir olan sys.float_info.maxve sys.float_info.max - (2 ** 970)50-50 şansı bir yoktur, böylece random.uniform(sys.float_info.max - (2 ** 970), sys.float_info.max)üretir sys.float_info.max:

>>> a, b = sys.float_info.max - (2 ** 970), sys.float_info.max
>>> values = [random.uniform(a, b) for _ in range(10000)]
>>> values.count(sys.float_info.max)  # should be roughly 5000
4997

5

"Birkaç kez" yeterli değil. 10.000 yeterli değil. random.uniform2 ^ 53 (9,007,199,254,740,992) farklı değer arasından seçim yapar. İlgilendiğiniz iki tanesi. Bu nedenle, tam olarak 0 veya 1 olan bir değer elde etmeden önce birkaç katrilyon rastgele değer üretmeyi beklemelisiniz . Bu yüzden, ancak bunu asla gözlemlemeyeceksiniz.


2
İçin uniform(0, 1)öyle imkansız üretmek için 1sonuç olarak. Çünkü fonksiyon basit olarak tanımlanır def uniform(a, b): return a + (b - a) * random()ve random()asla üretemez 1.0.
Martijn Pieters

2
@MartijnPieters Doğru olduğuna inanıyorum ve cevabınızı iptal ettim. O kadar şüpheliydim, ama emin değildim ve cevabımın ana iticili bir yana, bu yüzden izin ver :)
Ocaklar

1

Tam bir 0 (gösterilmemesi) gösterilmesi için gereken yineleme miktarını sayan bir döngü oluşturmayı deneyebilirsiniz.

Ayrıca Hobbs'un belirttiği gibi, uniformlyörneklenen değerlerin miktarı 9.007.199.254.740.992'dir. Bu, 0'ı görme olasılığının tam olarak 1 / 9,007,199,254,740,992 olduğu anlamına gelir. Hangi genel terimler ve yuvarlama anlamına gelir 0 bulmak için ortalama 10 kuatilyon örnek gerekir. Tabii ki ilk 10 denemede bulabilirsiniz, ya da asla.

Değerler için tanımlanan aralık bir parantez ile kapatıldığı için 1'i örneklemek imkansızdır, dolayısıyla 1 içermez.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.