1.经典概率算法抽奖
$tmpItems = ['电脑'=>10, '相机'=>50, '100元现金'=>500]; $proSum = array_sum($tmpItems); foreach ($tmpItems as $key => $proCur) { $randNum = mt_rand(1, $proSum); if ($randNum <= $proCur) { $resultId = $key; break; } else { $proSum -= $proCur; } }
从count($tmpItems)总样本中随机一个数,循环的判断是否小于currentValue,小于便是中奖,大于就从总样本中扔掉currentValue ,继续循环产生随机数判断概率是否落入小于currentValue区间内。
封装为函数,支持概率为小数点 (小数点位数越多数据量越大)
function get_prize($prizeItems) { $resultId = ''; $dec = explode('.', strval(min($prizeItems))); # 小数点拆分 $dec_len = isset($dec[1]) ? strlen($dec[1]) : ''; #小数点后长度 $radix = 1; # 乘积的基数 if ($dec_len) { for ($i = 1; $i <= $dec_len; $i++) { $radix*=10; } } $tmpItems = []; foreach ($prizeItems as $key => $value) { $tmpItems[$key] = $value * $radix; } $proSum = array_sum($tmpItems); foreach ($tmpItems as $key => $proCur) { $randNum = mt_rand(1, $proSum); if ($randNum <= $proCur) { $resultId = $key; break; } else { $proSum -= $proCur; } } return $resultId; } /** * 电脑 概率为0.02% 十万分之二 * 相机 概率为0.2% 万分之二 * 100元现金 概率为1.8% 百分之一点八 * 德芙巧克力 概率为40% 十分之四 * 谢谢参与 概率为57.98% 百分之五十七点九八 */ $prizeItems = ['电脑' => 0.0002, '相机' => 0.002, '100元现金' => 0.018,'德芙巧克力'=>0.4,'谢谢参与'=>0.5798]; print_r(get_prize($prizeItems));