java 均匀分布 算法_基于java.lang.Math.Random()的近似均匀分布特性实现的抽奖算法...

本文介绍了如何利用Java的Math.Random()方法实现一个近似均匀分布的抽奖算法。首先,根据奖品概率计算总概率并进行分块,然后通过Random()生成的随机数插入到分块列表中,最后返回插入位置作为中奖结果。此外,还讨论了抽奖逻辑中涉及的库存管理,并提醒在实际生产环境中要考虑线程安全和分布式事务等问题。
摘要由CSDN通过智能技术生成

在电商促销或一些直播小游戏中,抽奖是一种比较常见的玩法。很多时候,展现给用户的可能是一个大转盘,如下:

3053146fa542a20e51dc5a8758165fa3.png

通常我们会给出一堆奖品,每个奖品有各自的中奖概率,而且每个奖品可能还有库存的概念,就是说已经被抽完了的奖品是不再参与抽奖的。就拿陌陌里的这个大转盘来举例,奖品列表有爱心火箭、私人飞机、旋转木马、梦幻香水、口红、暖心奶茶、糖果、未中奖(未中奖可以看着是特殊的奖品)等8个奖品,每个奖品会根据其价值有不同的中奖概率,比如中糖果和暖心奶茶的概率高些,但中火箭的概率可能低很多。如果让你用java实现一个抽奖,你会怎么实现它呢?这正是我们今天要探讨的内容。

抽奖算法

在Java中,java.lang.Math.Random()方法本身基本可以保证大量测试的情况下避免高重复,且概率分布比较平均。所以我们根据奖品的概率列表基于java.lang.Math.Random()方法实现一个抽奖的工具类:

根据奖品的中奖概率列表probabilityList计算总概率sumRate;

根据总概率和各个奖品的概率对概率进行分块,得到分块列表blockList,比如传过来的概率列表是{0.25,0.15,0.6},那么分块区间就是0-0.25,0.25-0.4,0.4-1.0,blockList的集合就是{0.25,0.4,1.0};

根据java.lang.Math.Random()平均概率返回0到1之间数字的特性得到nextDouble;

把nextDouble的值按大小顺序插入到blockList中;

返回nextDouble插入的位置

抽奖逻辑

有了上面的抽奖算法,接下来我们分析下抽奖的逻辑是怎么实现的。为了更贴近使用场景,除了每个奖品有中奖概率外,增加一个库存的概念。因为有时候大奖并不是无限的,可能只有一个。在促销活动进行过程中,运营人员不一定一开始就把大奖的库存放出来,毕竟留在后面才更有悬念,如果大奖一放出来就被抽走了,用户的参与热情估计就没了,因为大家都是冲着大奖来的,就跟买彩票只想中500万一个道理。

定义一个奖品类Award,属性包含奖品名称、中奖概率、库存等。

接下来,我们模拟一下抽奖逻辑:

运行结果类似:

抽奖逻辑注意事项

上面的抽奖逻辑只是简单的单线程模拟抽奖算法的有效性,在生产环境中,还需要注意线程安全性、分布式事务等问题,抽奖都是高并发场景下,所以要处理好库存扣减以及库存扣减失败重抽等细节。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值