2014-02-05 174 views
3

我在論壇中發現了很多關於此問題的內容,但所有的答案都是針對問題提出的。我發現我最需要的是:Probability Random Number Generator by Alon Gubkin以固定概率生成隨機數

區別在於,阿隆要求給一張臉(這是六張)額外的機會。就我而言,我想分六個面孔的機會,使他們加起來達到100%。例如,面1有40%的機率,面2只有10%,面3有25%,...等。

我該怎麼做?

+0

用40 1s,10 2s,25 3s創建一個數組,然後選擇一個隨機項。 – zerkms

+0

http://stackoverflow.com/questions/445235/generating-random-results-by-weight-in-php – user2314737

回答

7

與線性概率的單個概率檢查可以很容易地與完成:

function checkWithProbability($probability=0.1, $length=10000) 
{ 
    $test = mt_rand(1, $length); 
    return $test<=$probability*$length; 
} 

例如,這將產生:

for($i=0; $i<10; $i++) 
{ 
    var_dump(checkWithProbability(1/3)); 
} 

喜歡的東西:

 
bool(false) 
bool(true) 
bool(false) 
bool(false) 
bool(false) 
bool(false) 
bool(false) 
bool(false) 
bool(true) 
bool(false) 

你也可以使用這一原則,讓您的邊緣與期望概率檢查:

function checkWithSet(array $set, $length=10000) 
{ 
    $left = 0; 
    foreach($set as $num=>$right) 
    { 
     $set[$num] = $left + $right*$length; 
     $left = $set[$num]; 
    } 
    $test = mt_rand(1, $length); 
    $left = 1; 
    foreach($set as $num=>$right) 
    { 
     if($test>=$left && $test<=$right) 
     { 
     return $num; 
     } 
     $left = $right; 
    } 
    return null;//debug, no event realized 
} 

的想法是使用geometry probability - 即一些線部分分開成片對應的長度,然後檢查我們的隨機數屬於哪個部分。

 

       0.75 0.9 
        | | 
        V V 
*--------*--*-----*-*--*--* <-- (length) 
^  ^^  ^ ^
|  | |  |  | 
0  0.4 0.5  0.8 1 

樣品將是:

$set = [ 
    1 => 0.4, 
    2 => 0.1, 
    3 => 0.25, 
    4 => 0.05, 
    5 => 0.1, 
    6 => 0.1 
]; 
for($i=0; $i<10; $i++) 
{ 
    var_dump(checkWithSet($set)); 
} 

有了這樣的結果:

 
int(1) 
int(2) 
int(2) 
int(6) 
int(3) 
int(1) 
int(1) 
int(6) 
int(1) 
int(1) 

可以增加$length - 從理論上講,這會增加隨機化檢驗的 「質量」,但是這不是太容易的事情 - 因爲mt_rand()使用僞隨機發生器,Mersenne Twister(並在理想的情況下,這不是真正的線性概率)

+0

這可能會造成我的朋友非常感激。這就是我一直在尋找的。非常感謝你^^。 –

1

在你的情況,你可能會從1到100,然後生成隨機:

if random in 1:40 -> face 1 
elseif random in 41:50 -> face 2 
and so on. 

當然,真正的代碼將是一個稍微複雜一些獲得真正的範圍,而不是硬編碼IFS

0

我可以想想一個非常簡單的解決方案。這不會改變隨機數發生器的生成模式,但會解釋結果以適應上述問題。我會要求隨機數生成器生成0到9之間的數字。然後執行以下映射,根據我分配給該值的概率將生成的數字的範圍分配給我的值:

If result <= 3, face=1 
else if result <=5, face =2 
else is result <=25 face =3 
//and so on 
2

一個非常簡單的方法是創建一個長度爲100的數組,在其中寫入「面」數字,將其拖動並獲取第一個元素。

因此,對於該陣列中的例如是40倍1,10X 2,25X 3.

小的代碼示例(未測試):

$probabilities = array(
    1 => 40, 
    2 => 10, 
    3 => 25, 
    4 => 5, 
    5 => 10, 
    6 => 10 
); 

$random = array(); 
foreach($probabilities as $key => $value) { 
    for($i = 0; $i < $value; $i++) { 
     $random[] = $key; 
    } 
} 

shuffle($random); 
echo $random[0];