çarpık normal dağılımdan rasgele sayılar üreten

8 Cevap php

En dilde rastgele (min, max) işlevini kullandığınızda, gibi dağıtım nedir?

i zaman% 20 için bir dizi sayı ve zaman% 80 için sayıları başka bir dizi üretmek istiyorsanız, ne kadar ben bu izler rasgele sayı dizi üretebilir?

ex) i rastgele sıklığını almalısınız ama "1" frekans "0" frekansına göre yaklaşık% 20 daha yüksek olmalıdır

8 Cevap

Bu bir olası bir yöntemdir:

ranges = [(10..15), (20..30)]
selector = [0, 0, 1,1,1,1,1,1,1,1] # 80:20 distribution array

# now select a range randomly    
random_within_range(ranges(selector[random(10)]))  


def random_within_range range
  rand (range.last - range.begin - (range.exclude_end? ? 1 : 0)) + range.begin
end

Yerleşik programlama dilleri en sözde rastgele jeneratörü örneğin aralığında her bir değer aralığı içinde herhangi bir başka değer olarak üretilen aynı olasılığına sahiptir, a uniform distribution üretir. Gerçekten de, bazı durumlarda bu gereklilik dil standart bir parçasıdır. , Python veya R gibi bazı dillerin ortak dağılımlarının çeşitli destekler.

Dil bunu desteklemiyorsa, ya böyle bir üniforma birinden bir normal dağılım gibi diğer dağıtımlara üretmek için matematiksel hileler kullanmak zorunda, ya da bu işlevi yerine üçüncü parti kütüphaneleri için bakabilirsiniz.

Senin sorunun bu yana ancak çok daha basit görünüyor the random variable is discrete (ve bunların basit türü, yani ikili). Bunlar için hile rastgele bir sayı belirli bir aralıkta, 0-999 demek, tekdüze dağılım oluşturur ve her değeri ile ilişkili oranlarda bu aralığı bölmek, eldeki davada bu gibi bir şey olurdu üretmek için:

  If (RandomNumber) < 200    // 20%
     RandomVariable = 0
  Else                       // 80%
     RandomVariable = 1

Bu mantık tabii n ayrı değişkenlere uygulanabilir.

Sizin soru örnekten biraz farklıdır. Bu yüzden de cevap olacak ve size gerçekten aradığınız ne cevap hangisi anlamaya olabilir.

1) Sizin örneği (I) yakut veya java biliyorum, yani ayı ile beni yok

  • İlk 0-1 bir tekdüze dağılım rastgele bir sayı üretmek, biz X. arayacağım
  • Ondan sonra, kurulum if / else (yani if ​​(x <.2) {1} else {0})

2) eğrilik olan normal dağılımdan rasgele sayılar oluşturuluyor

  • Bu tür serbestlik derecesi yüksek bir çarpık öğrenci T'nin dağılımı gibi çarpık dağılımlar içine bakabilirsiniz.
  • Ayrıca, normal CDF kullanmak ve sadece sayıları bu şekilde avlayabilir.
  • Burada bir tekdüze dağılım birden fazla rasgele sayılar ile bunu nasıl anlatılır bir paper hangi bulunuyor
  • Son olarak, kernal yoğunluk tahmini (Ben bu sofistike ancak bir şey değil arıyorsanız şüpheli) içerecektir parametrik olmayan bir yaklaşım kullanabilirsiniz.

Çoğu bilgisayar dilleri onların (sözde) rasgele tamsayı jeneratörler için tektip bir dağılıma sahip. Yani her tamsayı eşit muhtemeldir.

Lütfen Örneğin, zaman "1"% 55 ve zaman "0"% 45 istediğinizi varsayalım.

. Bu frekanslar, 1 ile 100 arasında rastgele bir sayı üretmek denemek üretilen sayı 1-55 ise, çıkış "1" eşitsiz almak için; Aksi çıktı "0".

Çoğu dil için, üretilen rasgele sayı o dilin içinde bir algoritma bağlı olabilir, ya da zaman, işlemci, tohum sayısı gibi çeşitli faktörlere dayalı olarak rasgele oluşturulmuş.

Dağılım normal değil. Aslında fonksiyon 5 tamsayılar dönerse, tüm 5 tamsayılar sonraki işlev çağrısında görünen adil bir şans olduğunu söylüyor. Bu, aynı zamanda dağıtım Kolluk olarak da bilinir.

Eğer zamanın% 80 zaman% 20 bir numara (örneğin 7), ve başka bir numara (örneğin 13) üretmek istiyorsanız Yani demek, böyle bir dizi yapabilirsiniz:

var arr = [7,13,13,13,13];
var picked = arr[Math.floor(Math.random()*arr.length)] ; 
// since Math.random() returns a float from 0.0 to 1.0

Yani böylece 7 görünen bir% 20 şansı var, ve 13% 80 şansı var.

Eğer iyi bir matematiksel anlayış istiyorsanız this lecture bakabilirsiniz.

Nasıl hakkında

var oneFreq = 80.0/100.0;
var output = 0;
if (Math.random() > oneFreq)
   output = 1;

ya, sen değerlerin 20% 0 ile 100 arasında olması ve% 80, 100 ve 200 arasında olmak istiyorum.

var oneFreq = 80.0/100.0;
var oneRange  = 100;
var zeroRange = 100;
var output = Math.random();
if (output > oneFreq)
   output = zeroRange + Math.floor(oneRange * (output - oneFreq));
else
   output = Math.floor(zeroRange * output);

Yakut Ben bu gibi yapardı:

class DistributedRandom
  def initialize(left, right = nil)
    if right
      @distribution = [0] * left + [1] * right
    else
      @distribution = left
    end
  end
  def get
    @distribution[rand @distribution.length]
  end
end

80:20 dağıtımı ile bir test Koşu:

test = [0,0]
rnd = DistributedRandom.new 80, 20   # 80:20 distribution
10000.times { test[rnd.get] += 1 }; puts "Test 1", test

Sağ tarafta% 20 daha fazla dağıtım ile bir test Koşu:

test = [0,0]
rnd = DistributedRandom.new 100, 120   # +20% distribution
10000.times { test[rnd.get] += 1 }; puts "Test 2", test

91 ayrık değerlerin üzerinde bir trigonometrik fonksiyonu ile özel dağıtım ile bir test Koşu, çıktı ancak önceki testlerde çok iyi uyum değildir:

test = [0,0]
rnd = DistributedRandom.new((0..90).map {|x| Math.sin(Math::PI * x / 180.0)})
10000.times { test[rnd.get] += 1 }; puts "Test 3", test