2011-03-14 11 views
8

ile tekdüze olmayan, tamsayı dağıtımı oluşturma Şu anda bir dizi ile tamsayıların eşit dağılımını oluşturmak için aşağıdaki kodu kullanıyorum. Ben twords dk değerini lehine bir dağılım verecek şekilde değiştirmek için çalışıyor ve neredeyse hiç üretir max değeri yaklaştıkça amtr1 <random>

int random(int min, int max) 
{ 
    static std::mt19937 gen; 
    std::uniform_int<int> dist(min, max); 
    return dist(gen); 

} 

(ı tohumlama kodu çıkardı). Önceden yapılmış tüm dağıtımları görebiliyorum, fakat bunların hiçbiri tam sayı değil. Ayrıca hangi belgelere dayanarak ihtiyacımın hangisine uyduğunu anlayamıyorum. , Tamsayılar ile kullanmak tek başına bir set izin nasıl documentation dayalı k = 2

Ama çözemiyorum wikipedia, gösterildiği gibi ben gelmiş en yakın ki-kare dağılımı ise k değeri.

Uygun olmayan üniforma, tamsayı dağıtımı kullanmak için işlevimi nasıl kurabilirim? 0 1'den daha sık olması gerektiği gibi, oldukça orada

henüz ama yardımcı olacaktır: Burada 0 ile 20 arasında std::poisson_distribution<int> dist((max - min) * .1); sonuçları şunlardır:


hala doğru dağıtımın seçimi konusunda çalışan Bir sonraki kişi, geldikçe daha fazla sonuç yayınlayacak.

int randomDist(int min, int max) 
{ 
    static std::mt19937 gen; 
    std::chi_squared_distribution<double> dist(2); 

    int x; 
    do 
    { 
    x = (int)(max*dist(gen)/10) + min; 
    } 
    while (x > max); 
    return x; 
} 

sonucunu veren:


de benim nihai çözüm yöntemleri bir arada oldu

+0

Bir Poisson dağılımında 0, 1'den küçük bir parametre seçerseniz, 0'dan daha sık olacaktır (şu anda (20−0) *. 1 = 2). Ayrıca, herhangi bir parametre ile geometrik bir dağılım ile elde edersiniz. Seçmeniz gereken, modellediklerinize bağlıdır: geometrik modeller, bir olay ortaya çıkana kadar geçen süre (örneğin, bir gol atmak için gereken atış sayısı), Poisson, bir zaman aralığı içinde sayı olayı oluşumlarını modeller (örneğin, sayı) Bir oyunda hedefler). – aaz

+1

Eh, bunu gerçek zamanlı bir genetik algoritma için kullanıyorum. Ayrı nesillere sahip olmak yerine, yeni bir organizmayı türetmek için zaman geldiğinde, onları fitness ile sıralıyorum ve ebeveynleri bu eğriye göre seçiyorum. – Zak

+0

@Zak - Geometrik dağılımı kullanarak seçim yaparsanız, daha sonra # 1 kazanır vs her bir ebeveynin seçimini # 1 kazanır vs (# 2 galibi (# 3 kazanan galibi)), nerede #i kazanır Herhangi bir #j'e karşı, i aaz

cevap

9

diğer tamsayı dağılımları var orada, onlar sadece yok Adlarında int var. Sınıf tanımlarında typedef IntType result_type var.

açıkladığınız gibi davranırlar olanları şunlardır: Eğer tarafından aralığını çevirmek gerekir

  • binomial_distribution(t, p)

    Bu aralıktaki sayıları üretir 0 ≤ x t≤ yüzden min. ortalama t · s olan, böylece bu numaralar, 0 ≤ x < ∞, ancak çok sayıda oluşturur 0.

    std::binomial_distribution<int> dist(max - min, .1);
    return dist(gen) + min;

  • poisson_distribution(λ)

    yakın P tercih giderek daha az olasıdır. Bir aralıkla sınırlamak için max'un üzerindeki herhangi bir şeyi sansürleyebilirsiniz. λ parametresi, ortalamadır.Bunu seçimi önceki örneğine uygun olacak şekilde:

    std::poisson_distribution<int> dist((max - min) * .1);
    int x;
    do
        x = dist(gen) + min;
    while (x > max);
    return x;

  • geometric_distribution(p)

    Ayrıca sayılar üreten 0 ≤ x < ∞, ancak 0 en olası sonuçtur ve sonraki her sayı bir öncekinden daha azdır.

    std::geometric_distribution<int> dist(1/((max - min) * .1 + 1));
    int x;
    do
        x = dist(gen) + min;
    while (x > max);
    return x;

Ayrıca sürekli dağılımların herhangi birini kullanabilirsiniz: Yine parametre seçimi önceki örnekte ortalamasını maç için double oluşturmak ve daha sonra yuvarlak int'a. dağıtımlarının yanı sıra

6

ancak aslında mümkün olduğunu ancak o (inverse transform sampling kullanarak, aynı zamanda aklınıza herhangi olasılık dağılımı işlevinin sizin tekdüze dağılım dönüştürebilir akılda tutmak, 'in büyük cevap @aaz söyledi Bazı "güzel" fonksiyonlar için) veya rejection sampling (her durumda uygulanabilir, ancak hesaplama pahallı olabilir).

Bana öyle geliyor

ihtiyaçlarınızı uyabilecek bir dağıtım exponential distribution (negatif) olacağını:

Exponential distribution

Neyse ki, bu ters dönüşüm örnekleme uygulayabileceğiniz için dağılımların biridir p ile

x = - ln(1-p)/lambda 

rastgele val: burada, bir muntazam bir örnek olan [0, 1] dağılımı, formülü uygulamak suretiyle, bir üstel bir dağılım elde edilebilir, yani Tekdüze dağılımdan ue ve lambda, üstel dağılımın parametresidir; Daha fazla bilgi için bkz. here.

Eğer x (a double olacak), sadece (gibi bir işlevle bunun veya yuvarlak:

int round(double val) 
{ 
    // warning: can give counterintuitive results with negative numbers 
    return int(val+0.5); 
} 

) int için döküm aldıktan sonra sizin sonucu elde etmek.


arada Düzenleme

, ben bile üstel dağılım zaten <random> (link) dahil olduğunu fark etmedi ... şey, hatta daha iyi, değil mi Kodu yazmanız gerekiyor, ama biraz teori asla :) israf edilmez.

İlgili konular