用java代码实现简单的概率随机抽奖算法,看完相信你也会

用java代码实现简单的概率随机抽奖算法,看完相信你也会

2023年7月29日发(作者:)

⽤java代码实现简单的概率随机抽奖算法,看完相信你也会⼯作需要,这两天写⼀个简单的java抽奖算法,因为逻辑简单不复杂,所以代码也很简洁,可以做到不同权重有不⽤的中奖概率(就类似于nginx集群⼀样,权重越⼤,概率越⾼),在这⾥将java概率随机抽奖代码抽离出来分享给⼤家。具体需求:给第三⽅推送数据,每个第三⽅根据预算会有不同的额度,考虑到服务器压⼒,所以采取了主动推送的⽅式,在每次推送的时候,需要根据第三⽅的配额计算出相应的概率,然后挑选⼀个第三⽅来推送。思路分析:从形式上看,跟随机抽奖⼏乎⼀模⼀样,都是在N中挑选1,⽽且还不是公平挑选,是带有概率性的。由于只分享概率随机抽奖的算法,所以就暂不考虑上限的情况,简单的说⼀下算法部分的实现思路(重点在于计算概率和区间,我这⾥是数量固定,所以概率很好算,具体真实的抽奖业务中会很复杂)。1、需要计算出每个第三⽅的配额在总配额中的占⽐情况:⾃⾝数量 / 总数量 = 各⾃占⽐;2、⽤100来做随机区间(1也可以),计算出每个区间的随机数值跨度:⽐例 * 100 = 区间跨度;3、根据跨度计算出每个区间的起始数值:从0开始按照每个跨度相加,最终将100拆分成N个区间;代码实现:import imal;import ist;import p;import ;import ;import ;/** * Created by Felix on 2019/07/10. */public class Lottery { /** * 计算⾃⾝相对于总体的⽐例 * * @param self ⾃⾝ * @param all 总体 * @return ⽐例 */ private static float getPercent(Integer self, Integer all) { // ⽐例计算出来会有很多⼩数,为了看得清晰,要四舍五⼊⼀下 return new BigDecimal(self / alue()).setScale(2, _HALF_UP).floatValue(); } /** * 根据⽐例,在100之间计算出区间跨度,进⼀步来计算中奖区间 * * @param percent ⽐例 * @return 跨度 */ private static int getRandom(float percent) { // 如果getPercent中没有四舍五⼊,那么就需要在这⾥四舍五⼊ return new BigDecimal(percent * 100).intValue(); } private void lottery() { Integer allAmount = 233;// 总配额(抽奖总次数) Integer allAmount = 233;// 总配额(抽奖总次数) List users = new ArrayList<>(); (new User(1, "张三", 11)); (new User(2, "李四", 22)); (new User(3, "王五", 5)); (new User(4, "赵六", 111)); (new User(5, "⽥七", 66)); (new User(6, "陈⼋", 18)); Map userOffsetMap = new HashMap<>(); float percent;// ⽐例 int span;// 跨度 int start = 0;// 区间开始 int end;// 区间结束 for (User user : users) { percent = getPercent(unt(), allAmount); span = getRandom(percent); // 按照跨度计算offset end = start + span; ((), new Offset(percent, span, start, end, unt())); // 因为区间不能超过100,所以每次都需要⽤新的数值+跨度 start = end; } // log for (Integer userId : ()) { Offset offset = (userId); n("⽤户: " + userId + ", 配额: " + unt() + ", 占⽐: " + cent() + ", 跨度: " + n() + ", 区间: [" + rt() + ", " + offse } Map countMap = new HashMap<>(); Integer userId; Integer num; for (int i = 0; i < allAmount; i++) { // 由于这⾥是递归处理,所以如果最后为null了,说明已经到达了所有⼈的配额上限(奖品或者抽奖次数⽤完了) userId = randomUser(userOffsetMap); if (userId == null) { break; } // 记录每个⽤户的中标次数,达到上限了就排除掉 num = (userId); if (num != null) { (userId, num + 1); } else { (userId, 1); } // 次数到了上限,移除⽤户(可看做:中奖之后移除⽤户) if ((userId) >= (userId).getAmount()) { (userId); } } // log for (Integer key : ()) { n(key + "中奖了" + (key) + "次,概率: " + getPercent((key), allAmount)); } } /** * 选中之后,会排除掉部分⽤户,递归调⽤,将机会让给别的⼈ * * @param userOffsetMap ⽤户offset信息 * @return 选中的⽤户 */ private Integer randomUser(Map userOffsetMap) { Integer userId = select(userOffsetMap); if (!y() && userId == null) { return randomUser(userOffsetMap); } return userId; } /** /** * 按照计算好的区间,随机获取⽤户(即视为中标了) * * @param userOffsetMap ⽤户offset信息 * @return 选中的⽤户 */ private Integer select(Map userOffsetMap) { // 计算⼀个随机数值,看他散列在哪个⽤户的区间 int rnum = new Random().nextInt(100); Offset offset; // 由于要兼顾每⼀个⽤户,所以需要循环(效率待定?) for (Integer userId : ()) { offset = (userId); // 100以内随机,所以需要是左侧需要等于,右侧不需要 if (rt() <= rnum && rnum < ()) { return userId; } } return null; } public static void main(String[] args) { new Lottery().lottery(); } class User { private int id; private String name; private int amount; public User(int id, String name, int amount) { = id; = name; = amount; } public int getId() { return id; } public void setId(int id) { = id; } public String getName() { return name; } public void setName(String name) { = name; } public int getAmount() { return amount; } public void setAmount(int amount) { = amount; } } class Offset { private float percent; private int span; private int start; private int end; private int amount; public Offset(float percent, int span, int start, int end, int amount) { t = percent; = span; = span; = start; = end; = amount; } public float getPercent() { return percent; } public void setPercent(float percent) { t = percent; } public int getSpan() { return span; } public void setSpan(int span) { = span; } public int getStart() { return start; } public void setStart(int start) { = start; } public int getEnd() { return end; } public void setEnd(int end) { = end; } public int getAmount() { return amount; } public void setAmount(int amount) { = amount; } }}实现效果:⽤java实现简单的概率随机抽奖算法跟代码中的参数做⼀下简单⽐对,总配额是233次(可视作为233次抽奖机会),6个⽤户按照不同⽐例分配不同的配额,全部抽奖完成之后看到的概率与配额的⽐例是⼀致的,说明按概率随机抽取成功!最后给⼤家赠送⼀本书籍《数据结构与算法经典问题解析》⾖瓣评分8.6 需要的朋友可以来简信我领取⽤java代码实现简单的概率随机抽奖算法,看完相信你也会本书的⽬的是使读者知晓数据结构和算法的设计原理和实现,⽽并⾮单纯地讲述定理及证明。为此,本书利⽤不同的复杂度来改善问题的解。对于许多问题,从穷举解法开始,逐步引⼊问题的最佳解,并给出算法所需的运⾏时间和空间。全书包含4个部分,第⼀部分(第1〜2章)主要描述抽象数据类型,给出算法的基本概念和复杂度分析与评价⽅法,并讨论⼏乎每章都要⽤到的递归和回溯技术第⼆部分(第3〜9章)介绍基本数据结构,包括链表、栈、队列、树、优先队列、堆、并査集和图,对于每⼀种数据结构分别采⽤多个实例进⾏具体的演⽰。第三部分(第10-15章)介绍数据处理的技术,包括排序、査找、选择、符号表、散列和字符串算法。第四部分(第16〜21章)重点介绍⼀些常⽤的算法设计技术及应⽤,包括贪婪算法、分治算法、动态规划算法、复杂度类型,并讨论对于⾯试和考试的⼀些有⽤话题。本书强调问题及分析,⽽不侧重于理论。可以作为从事计算机研究与开发的技术⼈员的参考书,特别是对正在准备⾯试、参加选拔性考试以及校园⾯试的读者尤为有⽤。不想把篇幅拉的太长需要的朋友可以来私信领取书籍免费获取⽅式:关注然后简信“资料”即可获得⽂档领取⽅式同时希望⼤家领到之后不要做收藏党!⽽是能够花⼀些时间认真看完⽂档,让它真正发挥出价值来。⽤java代码实现简单的概率随机抽奖算法,看完相信你也会⽤java代码实现简单的概率随机抽奖算法,看完相信你也会

发布者:admin,转转请注明出处:http://www.yc00.com/web/1690624229a380805.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信