带权重实现随机抽奖,如用户邀请人数越多中奖概率越高,或者不同数量的一二三四等奖等。
主要两种实现思路:
- 计算最小对等个体的总数,在总数中随机选择一个数字,判断数字落在的区间,取出对应的上层中奖个体。
- 计算非对等个体的中奖概率,正常情况下,所有的非对等个体中奖概率之和为1,在[0,1)中随机生成一个浮点数,判断浮点数落在的区间,取出区间对应的中奖个体。如还需要在非对等个体中选择一个最小对等个体,取其总数,随机选择一个即可。
词语解释:
- 最小对等个体:中奖概率相等的不可分割的最小个体,如一等奖5个,二等奖10个,总共15个奖品,每一个奖品就是一个最小对等个体,一等奖和二等奖就是其上层中奖个体。
- 非对等个体:中奖概率不相等的可分割的上层个体,如一等奖5个,二等奖10个,总共15个奖品,一等奖和二等奖就是非对等个体,其下的15个奖品就是一个最小对等个体。
方案一:直接选中最小对等个体
假设:有一二三四等奖分别5,10,20,40,每个奖品的中奖概率相等。
每次抽奖,先统计奖品总数,加和所有的奖品数量N,再通过随机数方法(random.uniform(0, N))取出一个随机数,随机数范围:(0,N],随机数即为中奖的个体。
在用户邀请人数越多中奖概率越高的场景下,邀请人数作为用户权重,当作数字个体处理,取到随机数之后,最后通过用户 * 权重累加(区间方法)计算出中奖用户个体。
用户邀请场景与几等奖场景最大的不同在于,几等奖场景抽出的是最小对等个体,用户邀请场景抽出的是非对等个体。
方案二:先选择非对等个体,再选择最小对等个体
假设:有一二三四等奖分别5,10,20,40,每个奖品的中奖概率相等。
每次抽奖,先计算所有等奖的中奖概率,所有等奖的概率加和等于1。再通过随机数方法(rand.nextDouble())取出一个浮点随机数,随机数范围:[0,1)。第一步取出中奖的非对等个体(区间方法),即几等奖。第二步取出几等奖下的一个奖品,因为某等奖下的奖品都是同质的,所以可以随便取出一个,可计算总数,通过随机数(random.uniform(0, N))随便取一个。
在用户邀请人数越多中奖概率越高的场景下,把用户邀请人数当作用户权重,计算出每个用户的中奖概率,执行抽奖直接取出中奖用户。这种方法就直接取出了非对等个体。
建议:
用户邀请场景使用方案二,免去抽取最小对等个体;
几等奖场景使用方案一,直接抽出最小对等个体。