2016-04-10 27 views
2

C++ rasgele sayı üreteci almak için mücadele ediyorum.Binom rasgele sayı üretme

  • jeneratör sadece 0 ve n arasındaki tamsayılar dönmelidir.
  • yüksek sayıda olasılığı daha yüksek olmalıdır düşük sayılar dönen olasılığı.

Örnek dağılımı:

1: ************************ 
2: ****************** 
3: ************** 
4: ************ 
5: ******** 
6: ***** 
7: **** 
8: *** 
9: ** 
10: * 

dağıtım tipi benim durumumda önemli değil. Denediğim şey, [0..2*n] değerleriyle binom dağılımı kullanmaktır. Daha sonra, zirveyi sıfırda tutmak için ortaya çıkan rastgele sayıları [0..n]'a dönüştürüyorum.

size_t n = 20; 
std::default_random_engine generator; 
std::binomial_distribution<int> distribution(n*2, 0.5f); 
int number = fabs(distribution(generator)-n); 

Ortaya numaraları: Sorum

0: ************************* 
1: *********************************************** 
2: ***************************************** 
3: ******************************** 
4: ********************** 
5: ************** 
6: ******** 
7: **** 
8: ** 
9: 
10-20: none. The numbers are very rare. 

: Nasıl doğru böyle bir algoritma uygularım? Daha yüksek değerlerin olasılığını nasıl arttırabilirim, böylece dağıtım kullanılan n'dan bağımsız olarak aynı kalır?

+0

için, sonra üretim işlev çağrıları belirli bir sayısı için 0 ve n/2 arasında rasgele sayı üretmek 0 ila N üretilmesi için geçiş olabilir; Geri ve ileriye geçiş yapmak size daha yüksek değerler daha düşük değerler vermelidir. Bunu genelleştirebilirsiniz. – user2296177

+0

@ user2296177 Bu ilginç bir fikir. Ancak rasgelelik kalitesi yeterince iyi olmazdı – maja

+1

std :: geometric_distribution' denediniz mi? –

cevap

0

ben aşağıdaki geçici çözümü kullanıyorum:

do { 
     number = (rand() % n) - (rand() % n); 
} while(number < 0 || number > n); 

Bu doğru bir dağılımını verir ama sayısı başına yaklaşık 0.9 yeniden deneme ihtiyacı beri çok yavaştır.

+1

Niçin int int = rand()% n, b = rand()% n; sayı = a> = b? a - b: b - a; '? – bipll

2

O bozunma hızını etkiler uygun parametre lambda exponential distribution

P(x) = lambda * Exp(-lambda * x) 

üretebilir.

Matematik kitaplığınızda (std :: exponential_distribution?) Kullanıma hazır üstel dağıtım yoksa, yalnızca inverse transform sampling (Smirnov's) method'u kullanın.

Delphi örneği

for i := 0 to 1000000 do begin 
    V := Trunc(-ln(Random())/lambda); 
    //Random function gives random value uniformly distributed on [0,1) 
    if V <= N then begin 
     Inc(H[V]); //histogram entry 
    end; 
    end;