说明
本文PHP语言去实现,只实现核心可控概率引擎,库存判断等其它业务需要其它代码配合实现。
代码
/**
* @function 封装可控概率的抽奖功能
* @param $arr array 数据集合
* @param $weight_key string 权重字段
* @return array 被选中的元素
*/
function controllableProbability($arr, $weight_key = 'weight') {
$total_probability = 0;
foreach($arr as $v) {
$total_probability = bcadd($total_probability, $v[$weight_key], 2);
}
$rand = mt_rand(1, intval($total_probability));
foreach ($arr as $val) {
if ($rand <= $val[$weight_key]) {break;}
$rand -= $val[$weight_key];
next($arr);
}
//想要返回key,使用return key($arr);
return current($arr);
}
调用
- weight权重概率字段,不是概率字段,不需要总和为100
- 如下,代表16个人抽奖,有10人是谢谢惠顾,有5人中2元,有1人中5元,有0人中50W。
$arr = [
['id' => 1, 'name' => '谢谢惠顾', 'weight' => 10],
['id' => 2, 'name' => '中2元', 'weight' => 5],
['id' => 3, 'name' => '中5元', 'weight' => 1],
['id' => 4, 'name' => '中50W', 'weight' => 0],
];
//参数1是数组,参数2是告诉controllableProbability函数哪个字段为改概率字段
controllableProbability($arr, 'weight');
验算
$a = 0; $b = 0; $c = 0; $d = 0;
for($i = 0; $i < 1600000; $i++) {
$res = controllableProbability($arr, 'weight');
if($res['id'] == 1) $a ++;
if($res['id'] == 2) $b ++;
if($res['id'] == 3) $c ++;
if($res['id'] == 4) $d ++;
}
echo "$a $b $c $d";
3轮抽奖,每轮抽160万次,可得以下表格:
轮次 | 谢谢惠顾实际次数 | 谢谢惠顾期望值 | 中2元实际次数 | 中2元期望值 | 中5元实际次数 | 中5元期望值 | 中50W实际次数 | 中50W期望次 |
---|---|---|---|---|---|---|---|---|
1 | 999323 | 1000000 | 500374 | 500000 | 100303 | 100000 | 0 | 0 |
2 | 1001144 | 1000000 | 498732 | 500000 | 100124 | 100000 | 0 | 0 |
3 | 999285 | 1000000 | 500662 | 500000 | 100053 | 100000 | 0 | 0 |
以谢谢惠顾为例纵向对比:
项目 | 第一轮 | 第2轮 | 第3轮 |
---|---|---|---|
谢谢惠顾实际次数 | 999323 | 1001144 | 999285 |
谢谢惠顾期望次数 | 100000 | 100000 | 100000 |
谢谢惠顾实际概率 | 62.46% | 62.57% | 62.46% |
谢谢惠顾期望概率 | 62.50% | 62.50% | 62.50% |
误差率 | -0.04% | +0.07% | -0.04% |
技术上:随机范围可控,但是随机值不可控,随机值可控就不叫随机了,有误差正常,本来随机就是个概率问题。
业务上:可通过库存的限制和其它业务逻辑来避免误差带来的问题。
数值上:若硬要实现0误差的精确控制,则需要动态获取权重值,抽中哪条数据,递减那条数据的权重值即可(同时要避免mt_rand();函数参数2小于参数1的情况出现)。
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容