lottery.phpphp
<?php
//轉自https://segmentfault.com/a/1190000007431893
/*
* 不一樣機率的抽獎原理就是把0到*(比重總數)的區間分塊
* 分塊的依據是物品佔整個的比重,再根據隨機數種子來產生0-* 中的某個數
* 判斷這個數是落在哪一個區間上,區間對應的就是抽到的那個物品。
* 隨機數理論上是機率均等的,那麼相應的區間所含數的多少就體現了抽獎物品機率的不一樣。
*/
function get_rand($proArr)
{
$result = array();
foreach ($proArr as $key => $val) {
$arr[$key] = $val['v'];
}
$proSum = array_sum($arr); // 計算總權重
$randNum = mt_rand(1, $proSum);
$d1 = 0;
$d2 = 0;
for ($i=0; $i < count($arr); $i++) {
$d2 += $arr[$i];
if ($i==0) {
$d1 = 0;
} else {
$d1 += $arr[$i-1];
}
if ($randNum >= $d1 && $randNum <= $d2) {
$result = $proArr[$i];
}
}
unset($arr);
return $result;
}
/*
* 使用較多的爲這個方法
*/
function get_rand1($proArr)
{
$result = array();
foreach ($proArr as $key => $val) {
$arr[$key] = $val['v'];
}
// 機率數組的總機率
$proSum = array_sum($arr);
asort($arr);
// 機率數組循環
foreach ($arr as $k => $v) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $v) {
$result = $proArr[$k];
break;
} else {
$proSum -= $v;
}
}
return $result;
}
/*
* 獎項數組
* 獎品id,名稱,比重
*/
$arr = array(
array('id'=>1,'name'=>'特等獎','v'=>1),
array('id'=>2,'name'=>'一等獎','v'=>5),
array('id'=>3,'name'=>'二等獎','v'=>10),
array('id'=>4,'name'=>'三等獎','v'=>12),
array('id'=>5,'name'=>'四等獎','v'=>22),
array('id'=>6,'name'=>'沒中獎','v'=>50)
);
//測試結果(10000次):
get_rand():
//count_1:0 count_2:490 count_3:1021 count_4:1172 count_5:2172 count_6:5145
//特等獎中獎率全爲:0
get_rand1():
//count_1:92 count_2:477 count_3:1017 count_4:1195 count_5:2264 count_6:4955
//整體感受 get_rand1() 更準確些......