之前有过这样的需求,抽奖活动,奖品按一定权重随机抽取,例如:
奖品 | a | b | c | d | e |
---|---|---|---|---|---|
权重 | 12 | 32 | 32 | 12 | 12 |
之前的做法是把每个奖品按照权重,重复加进一个数据,即:
1 | [a,a,a,a...b,b,b,b,b...c,c,c,c,c...d,d,d,d...e,e,e...] |
里面有12个a,32个b以此类推。然后用 array_rand() 选出一个。
这种方法首先会的到一个很大的数组,然后循环添加奖品也很费时。今天重新思考这个问题,可以用下面的方法:
- 将所有权重相加得到总和
- 以总和为最大值得到一个随机数
- 循环查找随机数在数组里的区间,进而得到结果
1 |
|
虽然这个算法里也有循环,但是通常礼物不会很多,计算量非常小。
最后给一个用 map 实现的方法,缺点是要用权重作为key,所以每个权重不能相同。https://www.cnblogs.com/exmyth/p/7100749.html