看代码
function lucky_draw()
{
// 奖品数组
$prize_arr = [
'0' => [
'id' => 1,
'prize' => '肯定中',
'pro' => 100
],
'1' => [
'id' => 2,
'prize' => 'apple',
'pro' => 0
],
'2' => [
'id' => 3,
'prize' => 'orange',
'pro' => 0
],
'3' => [
'id' => 4,
'prize' => 'banana',
'pro' => 0
],
'4' => [
'id' => 5,
'prize' => 'pear',
'pro' => 0
],
'5' => [
'id' => 6,
'prize' => 'watermelon',
'pro' => 0
]
];
// 提取概率
$proArr = [];
foreach ($prize_arr as $val) {
$proArr[$val['id']] = $val['pro'];
}
/****根据概率获取奖项id -- start 算法****/
$rid = '';
//概率数组的总概率精度
$proSum = array_sum($proArr);
//概率数组循环
foreach ($proArr as $key => $proCur) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $proCur) {
$rid = $key;
break;
} else {
$proSum -= $proCur;
}
}
unset($proArr);
/****根据概率获取奖项id -- end 算法****/
$res['yes'] = $prize_arr[$rid - 1]['prize']; //中奖项
unset($prize_arr[$rid - 1]); //将中奖项从数组中剔除,剩下未中奖项
shuffle($prize_arr); //打乱数组顺序
for ($i = 0; $i < count($prize_arr); $i++) {
$pr[] = $prize_arr[$i]['prize'];
}
$res['no'] = $pr;
echo json_encode($res);
}
算法解释
$proSum = array_sum($proArr);
foreach ($proArr as $key => $proCur) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $proCur) {
$rid = $key;
break;
} else {
$proSum -= $proCur;
}
}
unset($proArr);
return $rid;
$proArr是一个预先设置的数组(概率数 --数组),假设数组为:array(100,200,300,400),开始是从1,1000这个概率范围内筛选第一个数是否在他的出现概率范围之内, 如果不在,则将概率空间,也就是k的值减去刚刚的那个数字的概率空间,在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的。这样筛选到最终,总会有一个数满足要求。就相当于去一个箱子里摸东西,第一个不是,第二个不是,第三个还不是,那最后一个一定是。