1.奖品抽奖
以前做抽奖,有那种抽奖的算法,比如大转盘,有手机,积分,券等。
算法原理 + 完整示例
一、算法原理
这种抽奖算法叫区间概率映射法,核心思路:
把所有奖品的中奖概率,按统一精度放大成整数权重,保证总权重对应 100% 概率。
根据权重给每个奖品划分一段连续、不重叠的数字区间。
抽奖时随机生成一个数字,该数字落在哪个奖品的区间,就抽中对应奖品。
权重越大、区间越长,中奖概率越高,公平且精准。
二、完整示例
设定 6 种奖品,总概率严格为 100%,统一乘以 1000 转为权重:
表格
奖品概率与区间配置表
| 奖品 | 中奖概率 | 对应权重 | 分配数字区间 |
|---|---|---|---|
| 手机 | 0.9% | 9 | 1 ~ 9 |
| 50 元优惠券 | 5% | 50 | 10 ~ 50 |
| 10 元优惠券 | 20% | 200 | 51 ~ 200 |
| 100 积分 | 10% | 100 | 20~ 359 |
| 20 积分 | 24.1% | 241 | 360 ~ 600 |
| 谢谢参与 | 40% | 400 | 601 ~ 1000 |
抽奖结果示例
抽奖时随机生成 1~1000 范围内的整数,数字落于对应区间即中该奖品:
随机数 3 → 落在 1~9 → 中手机
随机数 30 → 落在 10~59 → 中 50 元优惠券
随机数 120 → 落在 60~259 → 中 10 元优惠券
随机数 300 → 落在 260~359 → 中 100 积分
随机数 500 → 落在 360~600 → 中 20 积分
随机数 800 → 落在 601~1000 → 谢谢参与
可以将1 ~ 9,10 ~ 59,60 ~ 259, ... ,一直到601 ~ 1000,每个区间作为一个数组元素,统一放到一个数组里面,抽奖的随机数就遍历这个数组,比如是90,那就落在数组60~259这个元素,就对应10元优惠券。
2.红包
这里看到别人的帖子也是有3种挺好的实现方式:
随机分配法
将金额转分避免浮点误差,按顺序为前 n-1 人随机分配,随机范围为 [1, 剩余金额 / 总金额 90% 最小值],且保证分配后剩余金额≥剩余人数(每人至少 1 分);最后 1 人直接获得剩余金额。缺点:先抢的人随机范围大,更容易抢到大额,分配不均。二倍均值法 --- 微信的手气红包用的就是这种
金额转分后,按顺序为前 n-1 人分配,核心是每次随机范围为 [1, 剩余金额 / 剩余人数 ×2 -1](分),保证每次随机金额的平均值相等;最后 1 人得剩余金额。特点:分配更均衡,红包金额与抢的先后顺序无关,避免两极分化。
https://cloud.tencent.com/developer/article/2599348?policyId=1004
- 线段切割法
将总金额(分)看作线段,n 人抢则随机生成 n-1 个不重复切割点(范围 [1, 总金额]),切割点排序后,相邻点的差值 / 首个点值 / 总金额减最后一个点值,即为每人的金额,最后转元。特点:所有人生成金额的概率均等,手气最佳的金额可能比二倍均值法更高,无先后顺序差异。