业务总结003:抽奖活动
C 端抽獎(jiǎng) UI 效果:
一、抽獎(jiǎng)活動(dòng)模型
上圖是大概的抽獎(jiǎng)活動(dòng)模型,可能一個(gè)抽獎(jiǎng)活動(dòng)會(huì)持續(xù)很多天,這里活動(dòng)抽獎(jiǎng)規(guī)則、獎(jiǎng)勵(lì)庫存都采用的都是當(dāng)日的概念,當(dāng)然也可以采用活動(dòng)持續(xù)時(shí)長的概念,具體看產(chǎn)品的意愿,畢竟產(chǎn)品大大說了算。
二、抽獎(jiǎng)算法
2.1 隨機(jī)概率
在獎(jiǎng)勵(lì)池隨機(jī)一個(gè)作為用戶獎(jiǎng)勵(lì),這種方式實(shí)現(xiàn)起來很簡單,但是產(chǎn)品不允許。為了吸引用戶參與抽獎(jiǎng),一般會(huì)設(shè)置一些成本較高的獎(jiǎng)勵(lì),這些成本較高的獎(jiǎng)勵(lì)肯定不希望被用戶大概率抽到。
2.2 庫存計(jì)算概率
獎(jiǎng)勵(lì)庫存與中獎(jiǎng)概率成正比,在很多場景下根據(jù)庫存計(jì)算中獎(jiǎng)概率也是一種比較好的選擇。普通的獎(jiǎng)勵(lì)一般在后臺會(huì)設(shè)置大量的庫存,而成本較高的獎(jiǎng)勵(lì)可能只會(huì)設(shè)置個(gè)位數(shù)的庫存。畢竟項(xiàng)目上線時(shí)不是由開發(fā)配置抽獎(jiǎng)活動(dòng),不排除運(yùn)營人員不清楚規(guī)則胡亂配置的可能,導(dǎo)致與預(yù)期不符。
2.3 指定中獎(jiǎng)概率
用戶能不能中獎(jiǎng)嚴(yán)格按照后臺各獎(jiǎng)勵(lì)的中獎(jiǎng)概率計(jì)算,便于各業(yè)務(wù)線人員理解。
三、抽獎(jiǎng)算法簡單實(shí)現(xiàn)
隨機(jī)概率比較簡單,一行代碼完事,這里就不說了。重點(diǎn)說下剩下兩種算法的實(shí)現(xiàn)方式,實(shí)現(xiàn)細(xì)節(jié)是在”0 - 總庫存“范圍內(nèi)生成一個(gè)隨機(jī)數(shù),然后把獎(jiǎng)勵(lì)庫存分段,分段區(qū)間與獎(jiǎng)勵(lì)一一對應(yīng),隨機(jī)數(shù)落在的那個(gè)分段區(qū)間對應(yīng)的獎(jiǎng)勵(lì)為用戶抽中的獎(jiǎng)勵(lì)。
下面是根據(jù)庫存計(jì)算中獎(jiǎng)概率的 demo,根據(jù)中獎(jiǎng)概率計(jì)算同理。
public class LotteryDemo {public static Random random = new Random();public static List<LotteryRewardSku> rewardSkuList;static {rewardSkuList = Arrays.asList(new LotteryRewardSku(1L, 10), new LotteryRewardSku(2L, 5), new LotteryRewardSku(3L, 1));}public static void main(String[] args) {Map<Long, Integer> rewardSkuStockMap = rewardSkuList.stream().collect(Collectors.toMap(LotteryRewardSku::getLotteryRewardSkuId, LotteryRewardSku::getStockNum));for (int i = 0; i < 5; i++) {LotteryRewardSku rewardSku = lotteryAlgorithm(rewardSkuList, rewardSkuStockMap);System.out.println(rewardSku.getLotteryRewardSkuId());}}private static LotteryRewardSku lotteryAlgorithm(List<LotteryRewardSku> rewardSkuList, Map<Long, Integer> rewardSkuStockMap) {int totalStock = (int) rewardSkuStockMap.values().stream().collect(Collectors.summarizingInt(i -> i)).getSum();// 在庫存總數(shù)中隨機(jī)一個(gè)數(shù)字,作為中獎(jiǎng)數(shù)int randNum = random.nextInt(totalStock) + 1;int next = 0;Long getRewardSkuId = null;// 庫存分段for (Map.Entry<Long, Integer> awardEntry : rewardSkuStockMap.entrySet()) {if (randNum <= next + awardEntry.getValue()) {getRewardSkuId = awardEntry.getKey();break;}next += awardEntry.getValue();}Long finalGetRewardSkuId = getRewardSkuId;return rewardSkuList.stream().filter(sku -> sku.getLotteryRewardSkuId().equals(finalGetRewardSkuId)).findFirst().orElse(null);}@Data@AllArgsConstructorpublic static class LotteryRewardSku {private Long lotteryRewardSkuId;private Integer stockNum;} }總結(jié)
以上是生活随笔為你收集整理的业务总结003:抽奖活动的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring IoC 源码系列(一)Be
- 下一篇: 天使轮的股份上限 不宜超过30%