php抽奖概率的算法
概率算法抽奖活动中用得是最多的了,下面就直接上代码:
<?php
/**
* Author: Dcr163
* Date: 2022/3/25
* Time: 10:25
*/
/**
* 获取中奖奖品下标 区间模式
* @param array $prizeList
* @return int|string|null
*/
function beganToDrawBetween(array $prizeList)
{
//总概率统计
$sumRatio = array_sum(array_column($prizeList, 'ratio'));
// 初始化随机数,奖品区间
$randNum = mt_rand(1, $sumRatio);
$leftInterval = 0;
$rightInterval = 0;
$lastRightInterval = 0;
foreach ($prizeList as $k => $prize) {
// 左区间
$leftInterval = $lastRightInterval;
// 右区间
$rightInterval = $leftInterval + $prize['ratio'];
// 上一个右区间
$lastRightInterval = $rightInterval;
// 判断随机数是否落在对应的区间
if ($leftInterval < $randNum && $randNum <= $rightInterval) {
return $k;
}
}
}
//模拟奖品列表
$prizeList = [
[
'id' => 1,
'prize_name' => '华为手机P50',
'ratio' => 1,
],
[
'id' => 2,
'prize_name' => '宝马X5',
'ratio' => 0,
],
[
'id' => 3,
'prize_name' => '魅族蓝牙耳机',
'ratio' => 20,
],
[
'id' => 4,
'prize_name' => '魔域手机清洁包',
'ratio' => 60,
],
[
'id' => 5,
'prize_name' => '医用冷敷面膜',
'ratio' => 40,
],
[
'id' => 6,
'prize_name' => '激光祛痘',
'ratio' => 30,
],
[
'id' => 7,
'prize_name' => '神秘盲盒',
'ratio' => 80,
],
[
'id' => 8,
'prize_name' => '高级写字笔',
'ratio' => 90,
],
[
'id' => 9,
'prize_name' => '熊猫公仔min',
'ratio' => 90,
],
[
'id' => 10,
'prize_name' => '熊猫公仔Plush',
'ratio' => 70,
],
];
//已中奖奖品数据
$luckyData = [];
//模拟10000次抽奖操作
for ($i = 1; $i <= 10000; $i++) {
$prizeIndex = beganToDrawBetween($prizeList);
if (is_null($prizeIndex)) continue;
$luckyData[] = $prizeList[$prizeIndex];
}
$html = '<table>';
$html .= '<th>';
$html .= '<td>奖品ID</td>';
$html .= '<td>奖品名称</td>';
$html .= '<td>中奖率</td>';
$html .= '</th>';
foreach ($luckyData as $prize) {
$html .= '<tr>';
$html .= '<td>' . $prize['id'] . '</td>';
$html .= '<td>' . $prize['prize_name'] . '</td>';
$html .= '<td>' . $prize['ratio'] . '</td>';
$html .= '<tr>';
}
$html .= '</table>';
echo $html;
经过10000
次测试,比例越高的中奖率越高,此时抽奖算法已经达到需求
Dcr163的博客
http://dcr163.cn/235.html(转载时请注明本文出处及文章链接)