84669 人學習
152542 人學習
20005 人學習
5487 人學習
7821 人學習
359900 人學習
3350 人學習
180660 人學習
48569 人學習
18603 人學習
40936 人學習
1549 人學習
1183 人學習
32909 人學習
万能的大神们有什么比较好的抽奖算法。
欢迎选择我的课程,让我们一起见证您的进步~~
return false
这是我之前写的。网上用流行的是两种算法,概率太高了。只好回归到课本里面的,直接把所有中奖的球和干扰球放到篮子里面,随机抽。而且抽奖直接抽,无需放回,我们只要再出奖后,奖品如果没了,就直接当成谢谢参与来出奖。
<?php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index(){ $prize=array( array('id'=>1,'name'=>'苹果电脑','chance'=>1), array('id'=>2,'name'=>'苹果手机','chance'=>2), array('id'=>3,'name'=>'1000元购物卡','chance'=>3), array('id'=>4,'name'=>'300元餐具','chance'=>4), array('id'=>5,'name'=>'100元手机充值卡','chance'=>5) ); $prize_form[0]=array('id'=>0,'name'=>'谢谢参与!'); foreach ($prize as $key => $value) { //格式化数组 $prize_form[$value['id']]=$value; if($value['chance']>0){ $p[$value['id']]=$value['chance']; } } $result=$this->get_rand($p); echo $prize_form[$result]['name']; } /* *奖项的ID不得为0,0默认为谢谢参与 *$proArr=array('1'=>'1','2'=>2) **/ private function get_rand($proArr) { //奖项数量 $prize_number=count($proArr); foreach ($proArr as $key => $value) { for($i=0;$i<$value;$i++){ //生成得奖球 $seekGroup[]='P'.$key; } } $chance_sum=array_sum($proArr); //干扰球数量 $disturb_number=$prize_number*100-$chance_sum; //生成干扰球 $disturb=range(1,$disturb_number); //将球放入篮子里 $basket=array_merge($seekGroup,$disturb); shuffle($basket); //抽奖 $rand=rand(0,$prize_number*100-1); if(strstr($basket[$rand], "P")){ $result=str_replace('P', '', $basket[$rand]); }else{ $result=0; } return $result; } } ?>
这个问题比较好解决哈,假设有100个奖品,发放对象也有100个人,对这100个奖品进行编号叫award0-99,对发放对象的100个人进行编号叫person0-99,代码实现如下:
<?php /** * 关注微信公众号:phpgod. * User: PHP技术大全 * Date: 2016/10/9 * Time: 9:47 */ $list = range(0,99); $awardList = $list; $personList = $list; shuffle($awardList); shuffle($personList); $targetAwardResult = array_combine($awardList,$personList); var_export($targetAwardResult);
/** * 随机算法 * * @param array 需要随机的一维数组 * ['10', '20', '30'] * * @return str 返回数组中的一个值 * 10 */ public function __getRand($pro_arr) { $result = ''; // 概率数组的总概率精度 $pro_sum = array_sum($pro_arr); // 概率数组循环 foreach ($pro_arr as $key => $pro_cur) { $rand_num = mt_rand(1, $pro_sum); if ($rand_num <= $pro_cur) { $result = $key; break; } else { $pro_sum -= $pro_cur; } } unset ($pro_arr); return $result; }
return false
这是我之前写的。网上用流行的是两种算法,概率太高了。只好回归到课本里面的,直接把所有中奖的球和干扰球放到篮子里面,随机抽。
而且抽奖直接抽,无需放回,我们只要再出奖后,奖品如果没了,就直接当成谢谢参与来出奖。
这个问题比较好解决哈,假设有100个奖品,发放对象也有100个人,对这100个奖品进行编号叫award0-99,对发放对象的100个人进行编号叫person0-99,代码实现如下: