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

摘要
阿里云产品通用代金券,最高可达2000元
分享一个活动中常用到的中奖概率算法
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 条

发表评论

游客 表情 看不清楚?点图切换