php红包摇摇刮刮乐活动抽奖算法

阅读1068评论0

分享一个活动中常用到的中奖概率算法

1、均等算法

/**
* 红包算法,均等
*
* @param number $money 红包总金额
* @param number $num 生成的红包数量
* @param number $max 红包最大金额
* @param number $min 红包最小金额
* @return array
*/
function getRedPackage($money, $num, $max, $min){
$data = [];
//判断最小红包乘数量是否大于总金额
if ($min * $num > $money || $max * $num < $money){
return $data;
}
while ($num >= 1){
$num--;
$kmix = max($min, $money - $num * $max);
$kmax = min($max, $money - $num * $min);
$kAvg = $money / ($num + 1);
//获取最大值和最小值的距离之间的最小值
$kDis = min($kAvg - $kmix, $kmax - $kAvg);
//获取0到1之间的随机数与距离最小值相乘得出浮动区间,这使得浮动区间不会超出范围
$r = ((float)(rand(1, 10000) / 10000) - 0.5) * $kDis * 2;
$k = round($kAvg + $r, 2);
$money -= $k;
$data[] = $k;
}
shuffle($data);
return $data;
}

2、摇奖算法

/**
* 抽奖算法(摇一摇,拉霸机,刮刮乐),非必中 总概率1-1000
* @param array $awards 奖品数组[['id'=>23,'prob'=>10]]
* @param string $prob 奖品概率
* @param string $key 返回的数组键值
* @return bool
*/
function drawRandom($awards = [],$prob = 'prob', $key = 'id'){
$rand = mt_rand(1,1000);
$proArr = [];
$pro = 0;
// 按概率抽奖
foreach($awards as $award){
$pro += $award[$prob];
$proArr[] = $pro;
}
foreach($proArr as $k=>$v){
if($rand < $v){
return $awards[$k][$key];
break;
}
}
return "";
}

3、抽奖必中

/**
* 抽奖,必中
*
* @param array $awards 奖品数组[奖品id=>概率]
* @return int 中奖ID
*/
function drawBitslap($awards = []){
if(empty($awards)) return false;
$result = getDrawRand($awards);
return $result;
}

function getDrawRand($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;
}

0 位网友评论:

欢迎来评论

请填写验证码