Bir aralıkta düzgün bir şekilde dağıtılmış değerler verimli bir şekilde nasıl oluşturulur?


12

Diyelim ki aralıktan rasgele sayılar kümesi oluşturmak istiyorum (a, b). Oluşturulan dizi, sıralandığı özelliğe de sahip olmalıdır. Bunu başarmanın iki yolunu düşünebilirim.

Izin nvermek oluşturulan dizinin uzunluğu olsun .

1. Algoritma:

Let `offset = floor((b - a) / n)`
for i = 1 up to n:
   generate a random number r_i from (a, a+offset)
   a = a + offset
   add r_i to the sequence r

2. Algoritma:

for i = 1 up to n:
    generate a random number s_i from (a, b)
    add s_i to the sequence s
sort(r)

Benim sorum şu, algoritma 1 algoritma 2 tarafından üretilen diziler kadar iyi diziler üretiyor mu?


BTW içinde sıralı rasgele sayıların bir listesini oluşturmak oldukça kolaydır R. Tekdüze bir aralıkta n rasgele sayı kümesi kümesi oluşturmak için [ a , bkn , aşağıdaki kod çalışır:. [bir,b]rand_array <- replicate(k, sort(runif(n, a, b))
RobertF

Yanıtlar:


18

İlk algoritma iki nedenden dolayı başarısız olur :

  1. zemininin alınması büyük ölçüde azaltabilir. Gerçekten de, b - a < n olduğunda, sıfır olacaktır, size değerleri aynı olan bir set verir!(bir-b)/nb-bir<n

  2. Zemini almadığınızda , ortaya çıkan değerler çok eşit dağıtılır. Örneğin, herhangi bir basit rastgele seçilmiş bir grupta iid üniform arasında (ki dağılımı özellikleri bir = 0 ve b = 1 , orada olduğu) ( 1 - 1 / n ) n1 / e 37 % büyük olmayacak şans üst aralıkta 1 - 1 /nbir=0b=1(1-1/n)n1/e37% ila 1 arasındadır . 1. algoritma ile % 100 var1-1/n1100%maksimumun bu aralıkta olma şansı. Bazı amaçlar için bu süper homojenlik iyidir, ancak genel olarak korkunç bir hatadır, çünkü (a) birçok istatistik mahvolur, ancak (b) nedenini belirlemek çok zor olabilir.

  3. Sıralamadan kaçınmak istiyorsanız, bunun yerine bağımsız üstel olarak dağıtılmış değişkenler oluşturun. Kümülatif toplamlarını , toplama bölerek aralığa ( 0 , 1 ) normalleştirin . En büyük değeri düşürün (her zaman 1 olacaktır ). ( A , b ) aralığına yeniden ölçeklendirin .n+1(0,1)1(bir,b)

Üç algoritmanın hepsinin histogramları gösterilmiştir. (Her biri 1000'in kümülatif sonuçlarını gösterir1000 bağımsız değerlik kümenin .) Algoritma 1 için histogramda gözle görülür bir değişiklik olmaması, buradaki sorunu göstermektedir. Diğer iki algoritmadaki değişim, tam olarak ne beklenmesi gerektiği ve rastgele bir sayı üretecinden ihtiyacınız olan şeydir .n=100

Birçok fazlası için dağılımı özellikleri bağımsız üniforma simüle yollarını (eğlendirirken), bkz Taklit bir Normal Dağılım gelen çizer kullanarak Üniforma Dağıtım gelen çizer .

Şekil: histogramlar

İşte Rfigürü üreten kod.

b <- 1
a <- 0
n <- 100
n.iter <- 1e3

offset <- (b-a)/n
as <- seq(a, by=offset, length.out=n)
sim.1 <- matrix(runif(n.iter*n, as, as+offset), nrow=n)
sim.2 <- apply(matrix(runif(n.iter*n, a, b), nrow=n), 2, sort)
sim.3 <- apply(matrix(rexp(n.iter*(n+1)), nrow=n+1), 2, function(x) {
  a + (b-a) * cumsum(x)[-(n+1)] / sum(x)
})

par(mfrow=c(1,3))
hist(sim.1, main="Algorithm 1")
hist(sim.2, main="Algorithm 2")
hist(sim.3, main="Exponential")

Cevabımdaki (sıralama düzeni istatistiklerine dayalı) algoritma hakkında ne düşünüyorsun? ;-)
ÇIKIŞ - Anony-Mousse

@Anony 3. algoritmamın daha az verimli bir versiyonudur. (Sizinki gereksiz yeniden ölçeklendirmeyi içeriyor gibi görünüyor.) Standart üniforma kütükleri alarak üstel değişkenler üretiyorsunuz.
whuber

6

İlk algoritma çok eşit aralıklı sayılar üretir

Ayrıca bkz . Düşük tutarsızlık serisi .

[0;1] aynı anda büyük 0,5'ten küçüktür: . Yaklaşımınızla şans 0'dır. Dolayısıyla verileriniz tekdüze değildir .

(Belirtildiği gibi, bu, örneğin tabakalaşma için istenen bir özellik olabilir. Halton ve Sobel gibi düşük tutarsızlık serileri do onların kullanım durumları vardır.)

Uygun ama pahalı bir yaklaşım (gerçek değerler için)

... beta dağıtılmış rasgele sayılar kullanmaktır. Düzgün dağılımın sıralama düzeni istatistiği beta dağılımlıdır. En küçük çizimleri rastgele çizmek için bunu kullanabilirsiniz , sonra ikinci en küçük, ... tekrar .

[0;1]Beta[1,n]n1-X~Beta[n,1]-ln(1-X)~Üstel[n]-ln(U[0;1])n

-ln(1-x)=-ln(1-u)n1-x=u1nx=1-u1n

Hangi aşağıdaki algoritmayı verir:

x = a
for i in range(n, 0, -1):
    x += (b-x) * (1 - pow(rand(), 1. / i))
    result.append(x) 

Sayısal dengesizlikler olabilir powve her nesne için hesaplama ve bölme, sıralamadan daha yavaş olabilir.

Tamsayı değerleri için farklı bir dağıtım kullanmanız gerekebilir.

Sıralama inanılmaz derecede ucuz, bu yüzden sadece kullanın

Ö(ngünlükn)


1
Sıralamadan kaçınmak için nedenler olabilir. Birincisi, çok sayıda rasgele değişken oluşturmak istediğinizde, birçoğu standart bir sıralama rutininin üstesinden gelemeyeceği kadar.
whuber

Kayan nokta matematiğini kullanarak toplamlarla ilgili sayısal sorunların çok daha erken bir sorun haline geldiğini düşünüyorum. (Ve yalancı rasgele sayılardaki döngüsel kalıplarla ilgili sorunlar!) Sıralama yaklaşımını terabaytlara ve dağıtılmış sistemlerde exabaytlara ölçeklemek oldukça kolaydır.
ÇIKIŞ - Anony-Mousse

1012

Tamam, onları saklamak zorunda kalmak bir argüman. Ama sonra benim yaklaşımım gerekecek, kümülatif toplamı kullanan varyant 3 çalışmaz.
QUIT - Anony-Mousse

Bu mükemmel bir nokta. Şimdi ekstra hesaplamaların erdemini görüyorum! (+1)
whuber

5

Ayrıca rastgele sayılarla ne yaptığınıza da bağlıdır. Sayısal entegrasyon problemleri için birinci yöntem (kat operatörünü kaldırarak düzeltildiğinde) üstün nokta kümesi üretecektir. Yaptığınız şey tabakalı örneklemedir ve topaklaşmayı önleme avantajına sahiptir. tüm değerlerinizi örneğin 0- (ba) / n aralığında almak imkansızdır. Diğer uygulamalar için bunun çok kötü olabileceğini söyledi, onunla ne yapmak istediğinize bağlı.


2
+1 Bence bu soruya özellikle Algoritma 1'i tabakalaşma açısından karakterize ederek faydalı bir katkı.
whuber
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.