2015-12-17 55 views
5

[M..N] aralığında bir rastgele sayı üretilmesi yeterince kolaydır. Bununla birlikte, bu aralıkta ortalama X (M < X < N) ile bir dizi rasgele sayı üretmek istiyorum.[M .... N] aralığında rastgele bir sayı üretin ve ortalama X

Örneğin, birinci aşağıdaki gibidir: M = 10000 N = 1000000 X = I olan tüm aralık [M..N] örtülecek kadar rasgele sayılar (büyük miktarda) oluşturmak istiyorum 20000 Ancak bu durumda N'ye yakın sayılar çok daha nadir görülmelidir. M'ye yakın sayılar, ortalama değerlerin X.

İstenilen hedef dili PHP olduğundan emin olmak için daha yaygın olmalıdır, ancak bu bir dil sorusu değildir.

+0

Dağıtımın nasıl görünmesi gerektiğine dair bir fikriniz var mı? Bunu iki eşit dağılım kullanarak (standart rasgele işlev olarak), bir tanesini [M.X] ve bir tane [X..N] ağırlıklı olarak kullanarak elde edersiniz, böylece ortalama X'dir. – Zong

+0

İlginç. Bu nedenle [M. X] 'de düzgün bir dağılımın ortalama değeri (M + X)/2 olur ve [X..N]' de düzgün bir dağılım, (X + N)/2 sağda olur mu? Ve sonra bu iki yolu, EV'leri X olacak şekilde ... ... ne demek istediniz? –

+0

Evet, hangi dağıtımın kullanılacağına karar vermek için ağırlıklı bir parayı çevirerek başlayabilirsiniz. Bu, gereksinimlerinizi karşılar, ancak istediğiniz "şekli" vermeyebilir. – Zong

cevap

1

Bunu başarmanın birçok yolu vardır ve hassasiyet konusundaki taleplerinize bağlı olarak çok farklı olacaktır. Aşağıdaki kod, normal dağıtıma göre 68-95-99.7 rule, ortalama% 15 standart sapma ile kullanır.

It does not:

  • tam hassasiyet sağlamak. Buna ihtiyacınız varsa, gerçek ortalamayı hesaplamanız ve eksik miktarı telafi etmeniz gerekir.
  • , dinamik olarak dağıtılmış bir eğri oluşturdu, çünkü üç parça (68-95-99.7) tüm gruplarında eşit kabul edildi.

Ancak sana bir başlangıç ​​veriyor:

<?php 

$mean = (int)$_GET['mean']; // The mean you want 
$amnt = (int)$_GET['amnt']; // The amount of integers to generate 
$sd = $mean * 0.15; 
$numbers = array(); 
for($i=1;$i<$amnt;$i++) 
{ 
    $n = mt_rand(($mean-$sd), ($mean+$sd)); 
    $r = mt_rand(10,1000)/10; // For decimal counting 
    if($r>68) 
    { 
     if(2==mt_rand(1,2)) // Coin flip, should it add or subtract? 
     { 
      $n = $n+$sd; 
     } 
     else 
     { 
      $n = $n-$sd; 
     } 
    } 
    if($r>95) 
    { 
     if(2==mt_rand(1,2)) 
     { 
      $n = $n+$sd; 
     } 
     else 
     { 
      $n = $n-$sd; 
     } 
    } 
    if($r>99.7) 
    { 
     if(2==mt_rand(1,2)) 
     { 
      $n = $n+$sd; 
     } 
     else 
     { 
      $n = $n-$sd; 
     } 
    } 
    $numbers[] = $n; 
} 

arsort($numbers); 
print_r($numbers); 

// Echo real mean to see how far off you get. Typically within 1% 

/* 
$sum = 0; 

foreach($numbers as $val) 
{ 
    $sum = $sum + $val; 
} 

echo $rmean = $sum/$amnt; 
*/ 

?> 

yardımcı olur Umut!