写点什么

大转盘抽奖

作者:Rubble
  • 2022 年 4 月 16 日
  • 本文字数:1637 字

    阅读完需:约 5 分钟

​ 抽奖是一种常用的营销工具。抽奖活动产生至今已许多年,一直被各行各业所采用,原因是它契合了人们的消费心理。对消费者而言,“占便宜”是永恒的追求,“以小博大”也满足了顾客追求刺激的心理。而且与其他活动形式相比,大转盘抽奖活动操作简单,趣味性强,满目奖品吸引用户,参与度高,可以刺激沉睡的用户,是促活拉新的不二之选。


转盘抽奖常常用在提交表单,抽奖定向引流。支付完成订单,抽奖给予概率性的奖励,或者定向引流。

抽奖算法

抽奖算法的基本思想是随机一个数,看随机数落在哪个区间。


现有 A、B、C 三项奖品,概率分别是万分之 10,20,30。则谢谢参与 D(也作为一个奖项)的概率是 10000-10-20-30;


0__ 10 __ 30__60__10000


则获奖区间


A: [0,10]


B: [10,30]


C: [30,60]


D: [60,10000]


random 一个 0-10000 的随机数,落在哪个区间,即中了哪个奖项。


实现代码


import java.util.HashMap;import java.util.Map;import java.util.Map.Entry;
import cn.hutool.core.util.RandomUtil;import cn.hutool.core.util.StrUtil;
/** * @author lvzihai * @date 2022/4/15 **/public class LotteryA {

private static int draw(){ int totalCount = 10000; int pa = 10; int pb = 20; int pc = 30; // 谢谢参与 int pd = totalCount -pa-pb-pc; int[] gifts = new int[]{pa,pb,pc,pd};
int[] giftRange = new int[gifts.length]; int sum = 0; for (int i = 0; i < gifts.length; i++) { sum+=gifts[i]; giftRange[i] = sum; } StrUtil s;
int randomVal = RandomUtil.randomInt(totalCount); for (int i = 0; i < giftRange.length; i++) { if(randomVal<giftRange[i]){ return i; } }
return -1; }
public static void main (String[] args) { Map<Integer,Integer> map = new HashMap<>(); int totalCount = 100000; for (int i = 0; i < totalCount; i++) { int index = draw(); Integer val = map.get(index); val = val==null?1:val+1; map.put(index,val); } // 统计概率 万分之X for (Entry<Integer, Integer> entry : map.entrySet()) { System.out.println(entry.getKey()+" "+10000.0*entry.getValue()/totalCount); } }}
复制代码

总概率不为 1 的算法

对于总概率不为 1 的改进算法。比如概率: A:0.1 B:0.2,C:0.3,D:0.6,将所有概率求和得到总概率,再计算每项的相对概率。


将随机值添加到序列并排序,通过indexOf来获取随机值所在的区间


List<Double> orignalRates = Arrays.asList(0.1,0.2,0.3,0.6);
public static int lottery (List<Double> orignalRates) { if (orignalRates == null || orignalRates.isEmpty()) { return -1; }
int size = orignalRates.size();
// 计算总概率,这样可以保证不一定总概率是1 double sumRate = 0d; for (double rate : orignalRates) { sumRate += rate; }
// 计算每个物品在总概率的基础下的概率情况 List<Double> sortOrignalRates = new ArrayList<Double>(size); Double tempSumRate = 0d; for (double rate : orignalRates) { tempSumRate += rate; sortOrignalRates.add(tempSumRate / sumRate); }
// 根据区块值来获取抽取到的物品索引 double nextDouble = Math.random(); // 将随机值添加到序列并排序,通过indexOf来获取随机值所在的区间 sortOrignalRates.add(nextDouble); Collections.sort(sortOrignalRates);
return sortOrignalRates.indexOf(nextDouble); }
复制代码
总结

抽奖算法整体思想是把奖项依次排列,谢谢参与也作为一个奖项,排列顺序无关,然后 random 一个随机数,看随机数落在哪个区间,即哪个奖项。对于有库存的奖项,可以单独计算库存,库存用完,直接返回谢谢参与。

用户头像

Rubble

关注

还未添加个人签名 2021.06.01 加入

还未添加个人简介

评论

发布
暂无评论
大转盘抽奖_4月日更_Rubble_InfoQ写作平台