该过年了。各个公司都要搞年会,刚好近期在做一个年会系统;
需求: 单个奖品。可以设置部分人中奖概率,和奖品得奖人数,最终算出中奖人;
算法实现:
<?php
/**
* $prize_arr 参与抽奖人员数据
* id: 一般是成员ID
* name 姓名
* v 得奖概率
***/
$prize_arr = array(
'0' => array('id'=>1,'name'=>'小王','v'=>1),
'1' => array('id'=>2,'name'=>'小李','v'=>5),
'2' => array('id'=>3,'name'=>'小张','v'=>10),
'3' => array('id'=>4,'name'=>'小二','v'=>12),
'4' => array('id'=>5,'name'=>'小菜','v'=>22),
'6' => array('id'=>6,'name'=>'小范','v'=>50),
'7' => array('id'=>7,'name'=>'小范01','v'=>50),
'8' => array('id'=>8,'name'=>'小范02','v'=>50),
'9' => array('id'=>9,'name'=>'小范03','v'=>50),
'10' => array('id'=>10,'name'=>'小范04','v'=>50),
'11' => array('id'=>11,'name'=>'小范05','v'=>50),
'12' => array('id'=>12,'name'=>'小范06','v'=>50),
'13' => array('id'=>13,'name'=>'小范07','v'=>50),
'14' => array('id'=>14,'name'=>'小范08','v'=>50),
'15' => array('id'=>15,'name'=>'小范09','v'=>100),
'16' => array('id'=>16,'name'=>'小范10','v'=>100),
);
foreach ($prize_arr as $key => $val) {
$arr[$key] = $val['v'];
}
$total_num = '3'; //设定得中奖人数量
$temp_rest=array();
for($i=0;$i<$total_num;$i++)
{
$rid = get_rand($arr); //根据概率获取人员ID
$temp_rest[]= $prize_arr[$rid]; //中奖项
unset($prize_arr[$rid]);
unset($arr[$rid]);
}
print_r($temp_rest);//得出结果
//得出当前中奖人
function get_rand($proArr) {
$result = '';
//概率数组的总概率精度
$proSum = array_sum($proArr);
//概率数组循环
foreach ($proArr as $key => $proCur) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $proCur) {
$result = $key;
break;
} else {
$proSum -= $proCur;
}
}
unset ($proArr);
return $result;
}
有用到得小伙伴可以拿去用!
有一个问题,请大家思考一下:如果我设置某一个人得中奖概率是100% ,是不是一定中奖?
答案是否定得。
这个问题我们讨论过。抽奖不允许这么黑暗,你的概率高。只是你的机会大一点,但不一定就是你得奖!(当然你也可以加。不过我是坚决抵制这种可耻行为的!)
最终代码实现如下:
<?php
/**
* $prize_arr 参与抽奖人员数据
* id: 一般是成员ID
* name 姓名
* v 得奖概率
***/
$prize_arr = array(
'0' => array('id'=>1,'name'=>'小王','v'=>1),
'1' => array('id'=>2,'name'=>'小李','v'=>5),
'2' => array('id'=>3,'name'=>'小张','v'=>10),
'3' => array('id'=>4,'name'=>'小二','v'=>12),
'4' => array('id'=>5,'name'=>'小菜','v'=>22),
'6' => array('id'=>6,'name'=>'小范','v'=>50),
'7' => array('id'=>7,'name'=>'小范01','v'=>50),
'8' => array('id'=>8,'name'=>'小范02','v'=>100),
'9' => array('id'=>9,'name'=>'小范03','v'=>50),
'10' => array('id'=>10,'name'=>'小范04','v'=>50),
'11' => array('id'=>11,'name'=>'小范05','v'=>50),
'12' => array('id'=>12,'name'=>'小范06','v'=>50),
'13' => array('id'=>13,'name'=>'小范07','v'=>50),
'14' => array('id'=>14,'name'=>'小范08','v'=>50),
'15' => array('id'=>15,'name'=>'小范09','v'=>100),
'16' => array('id'=>16,'name'=>'小范10','v'=>100),
);
foreach ($prize_arr as $key => $val) {
$arr[$key] = $val['v'];
}
$total_num = '8'; //设定得中奖人数量
$temp_rest=array();
for($i=0;$i<$total_num;$i++)
{
$rid = get_rand($arr,true); //根据概率获取人员ID
$temp_rest[]= $prize_arr[$rid]; //中奖项
unset($prize_arr[$rid]);
unset($arr[$rid]);
}
print_r($temp_rest);//得出结果
/****
* 得出当前中奖人
* $is_status是否开启概率为100必中: 默认不开启
***/
function get_rand($proArr,$is_status = false) {
$result = '';
if($is_status){
$rest = get_100($proArr); //调用获取100命中
}else{
$rest ='';
}
if(empty($rest) || !isset($rest)){
//概率数组的总概率精度
$proSum = array_sum($proArr);
//概率数组循环
foreach ($proArr as $key => $proCur) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $proCur) {
$result = $key;
break;
} else {
$proSum -= $proCur;
}
}
}else{
$result = $rest;
}
unset ($proArr);
return $result;
}
function get_100($arr_mast){
$result = '';
foreach ($arr_mast as $key => $value_mast) {
if($value_mast== 100){
$result = $key;
break;
}
}
unset ($arr_mast);
return $result;
}