日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

天天福利抽奖-JAVA概率抽奖

發(fā)布時(shí)間:2023/12/29 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 天天福利抽奖-JAVA概率抽奖 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

搞了個(gè)抽獎(jiǎng)活動(dòng),中大獎(jiǎng)中的簡(jiǎn)直爽歪歪?

?

不過還是要偷偷告訴你:抽獎(jiǎng)是有內(nèi)幕的~~~(不能讓領(lǐng)導(dǎo)看到,會(huì)被打?)

總在各種app上看到轉(zhuǎn)盤抽獎(jiǎng),翻牌抽獎(jiǎng),每次抱著中最大獎(jiǎng)的心,換來的都是未中獎(jiǎng)的提示,可謂是竹籃打水一場(chǎng)空,屢戰(zhàn)屢敗,屢敗屢戰(zhàn)~

現(xiàn)在就聊聊中獎(jiǎng)的事,搬好小板凳排隊(duì)做好了??♂????♂????♂?????????????

一、實(shí)現(xiàn)思路(這個(gè)應(yīng)該不難理解吧~)


每個(gè)獎(jiǎng)品都有對(duì)應(yīng)的中獎(jiǎng)概率,先對(duì)所有獎(jiǎng)品中獎(jiǎng)概率求和
計(jì)算出每個(gè)獎(jiǎng)品在0-1之間所占的區(qū)間塊
隨機(jī)產(chǎn)生0-1之間的隨機(jī)數(shù),隨機(jī)數(shù)落在哪個(gè)區(qū)間,就是中獎(jiǎng)哪個(gè)?
例如現(xiàn)有以下獎(jiǎng)品:?
獎(jiǎng)品A 中獎(jiǎng)概率為 0.1?
獎(jiǎng)品B 中獎(jiǎng)概率為 0.01?
獎(jiǎng)品C 中獎(jiǎng)概率為 0.001?
獎(jiǎng)品D 中獎(jiǎng)概率為 0.8

第一步:求出概率總和 0.1+0.01+0.001+0.8 = 0.911?
第二步:計(jì)算每個(gè)獎(jiǎng)品的所占區(qū)間塊?
獎(jiǎng)品A: 0.1 / 0.911 = 0.1098?
獎(jiǎng)品B: (0.1+0.01)/ 0.911 = 0.1207?
獎(jiǎng)品C:(0.1+0.11+0.001)/ 0.911 = 0.1218?
獎(jiǎng)品D:(0.1+0.11+0.001+0.8)/ 0.911 = 1?
則:?
獎(jiǎng)品A的所占區(qū)間為:0~0.1098?
獎(jiǎng)品B的所占區(qū)間為:0.1098~0.1207?
獎(jiǎng)品C的所占區(qū)間為:0.1207~0.1218?
獎(jiǎng)品D的所占區(qū)間為:0.1218~1
到此為止思路應(yīng)該了解了,不過我要做的是這個(gè)的升級(jí)版

根據(jù)不同類型的人分別設(shè)置概率(emm~換句話說根據(jù)身份設(shè)置概率發(fā)放獎(jiǎng)品)

特此說明一下:里面的概率10代表10%,可以精確到小數(shù)點(diǎn)后兩位,比如 0.01%

二、干貨如下

import lombok.Data; import lombok.ToString; /*** @Author: yansf* @Description:獎(jiǎng)勵(lì)實(shí)體* @Date:Creat in 10:35 AM 2019/1/16* @Modified By:*/ @Data @ToString public class RewardDto {/*** 獎(jiǎng)品id*/private int welfareId;/*** 天天福利管理Id(Welfare_ManagerId)*/private int welfareMgrId;/*** 獎(jiǎng)品名稱*/private String welfareName;/*** 獎(jiǎng)品類型(游戲幣10 vip試用20 京東卡30)*/private int welfareType;/*** 獎(jiǎng)品數(shù)量(單個(gè)獎(jiǎng)品上限)*/private int AwardCount;/*** 獎(jiǎng)品值*/private int welfareValue;/*** 獎(jiǎng)品概率 (10代表10%)*/private int AwardPct;/*** 子概率-A類概率*/private int APct;/*** 子概率-B類概率*/private int BPct;/*** 子概率-C類概率*/private int CPct;/*** 子概率-D類概率*/private int DPct;/*** 獎(jiǎng)品剩余庫存*/private int remainderAmount;/*** 獎(jiǎng)品配置庫存*/private int totalAmount;} /*** @Author: yansf* @Description:userType 1-A類人 2-B 5-C 7-D* @Date: 11:28 AM 2019/9/5* @Modified By:*/public RewardDto lottery1(int userId, boolean isVip, int userType) {RewardDto dto = null;RewardDto dto1 = null;//獲取獎(jiǎng)品配置信息List<RewardDto> list = welfareMapper.getRewardPctList();if (dto == null) {OptionalInt s = list.stream().filter(e -> e.getWelfareType() == 10).mapToInt(RewardDto::getWelfareValue).min();dto1 = list.stream().filter(e -> e.getWelfareValue() == s.getAsInt()).findAny().orElse(null);}//移除庫存為0的獎(jiǎng)品list.removeIf(e -> e.getRemainderAmount() == 0);var firstReward = welfareMapper.getWelfareReceiveRecord(userId, null, null);//近一個(gè)月內(nèi)是否中獎(jiǎng)過vip試用,不再抽中vipvar vipTrial = welfareMapper.getvipTrialRecord(userId);//如果已經(jīng)是vip,則不可抽vipif (isVip || vipTrial > 0) {list.removeIf(e -> e.getWelfareType() == 20);}//如果活動(dòng)間第一次抽獎(jiǎng),中最小的獎(jiǎng)的概率為0if (firstReward <= 0 && (list.size() >= 2)) {//移除最小獎(jiǎng)的配置OptionalInt s = list.stream().filter(e -> e.getWelfareType() == 10).mapToInt(RewardDto::getWelfareValue).min();list.removeIf(e -> e.getWelfareValue() == s.getAsInt() && e.getWelfareType() == 10);}if (list != null && list.size() > 0) {//總的概率區(qū)間float totalPro = 0f;//存儲(chǔ)每個(gè)獎(jiǎng)品新的概率區(qū)間List<Float> proSection = new ArrayList<Float>();DecimalFormat df = new DecimalFormat("######0.00");int random = -1;try {//計(jì)算總權(quán)重double sumWeight = 0;for (RewardDto award : list) {if (userType == 1) {sumWeight += award.getAPct();} else if (userType == 2) {sumWeight += award.getBPct();} else if (userType == 5) {sumWeight += award.getCPct();} else if (userType == 7) {sumWeight += award.getDPct();}}//產(chǎn)生隨機(jī)數(shù)double randomNumber;randomNumber = Math.random();//根據(jù)隨機(jī)數(shù)在所有獎(jiǎng)品分布的區(qū)域并確定所抽獎(jiǎng)品double d1 = 0;double d2 = 0;for (int i = 0; i < list.size(); i++) {if (userType == 1) {d2 += Double.parseDouble(String.valueOf(list.get(i).getAPct())) / sumWeight;if (i == 0) {d1 = 0;} else {d1 += Double.parseDouble(String.valueOf(list.get(i - 1).getAPct())) / sumWeight;}} else if (userType == 2) {d2 += Double.parseDouble(String.valueOf(list.get(i).getBPct())) / sumWeight;if (i == 0) {d1 = 0;} else {d1 += Double.parseDouble(String.valueOf(list.get(i - 1).getBPct())) / sumWeight;}} else if (userType == 5) {d2 += Double.parseDouble(String.valueOf(list.get(i).getCPct())) / sumWeight;if (i == 0) {d1 = 0;} else {d1 += Double.parseDouble(String.valueOf(list.get(i - 1).getCPct())) / sumWeight;}} else if (userType == 7) {d2 += Double.parseDouble(String.valueOf(list.get(i).getDPct())) / sumWeight;if (i == 0) {d1 = 0;} else {d1 += Double.parseDouble(String.valueOf(list.get(i - 1).getDPct())) / sumWeight;}}if (randomNumber >= d1 && randomNumber <= d2) {random = i;break;}}} catch (Exception e) {System.out.println("生成抽獎(jiǎng)隨機(jī)數(shù)出錯(cuò),出錯(cuò)原因:" + e.getMessage()); // throw e;}if (random != -1) {dto = list.get(random);}}if (dto == null) {dto = dto1;}return dto;} /*** @Author: yansf* @Description:抽獎(jiǎng)測(cè)試* @Date: 3:35 PM 2019/8/19* @Modified By:*/@GetMapping(value = "lottery")public ResponseUtil lottery(int userId, boolean isVip, int userType) {int coin = 0;int vip = 0;int jd = 0;RewardDto result = new RewardDto();List<RewardDto> list = new ArrayList();System.out.println("抽獎(jiǎng)開始");for (int i = 0; i < 1000; i++) {result = welfareService.lottery(userId, isVip, userType);if (result.getWelfareType() == 10) {coin += 1;} else if (result.getWelfareType() == 20) {vip += 1;} else if (result.getWelfareType() == 30) {jd += 1;}list.add(result);}Map<String, List<RewardDto>> count = list.stream().collect(Collectors.groupingBy(RewardDto::getWelfareName));if (result != null) {return ResponseUtil.response(200, "游戲幣:" + coin + ",vip:" + vip + ",京東卡:" + jd, count);} else {return ResponseUtil.response(500, "未中獎(jiǎng)", count);}}

此處循環(huán)1000次,使用非vipD類人做一下測(cè)試,結(jié)果如下圖

概率抽獎(jiǎng)其實(shí)很簡(jiǎn)單,如果又要分獎(jiǎng)品概率,又要根據(jù)不同人設(shè)置不同的概率,那就比重相乘然后相加,舉個(gè)簡(jiǎn)單的例子:

//計(jì)算總權(quán)重double sumWeight = 0;for (RewardDto award : list) {if (userType == 1) {//此處獎(jiǎng)品概率*不同人抽到該獎(jiǎng)品的概率sumWeight += award.getAPct()*avard.getPct();} } for (int i = 0; i < list.size(); i++) {if (userType == 1) { //概率相乘d2 += Double.parseDouble(String.valueOf(list.get(i).getAPct()*list.get(i).getPct())) / sumWeight;if (i == 0) {d1 = 0;} else {d1 += Double.parseDouble(String.valueOf(list.get(i - 1).getAPct()*list.get(i).getPct())) / sumWeight;}}

看到這,你應(yīng)該學(xué)會(huì)了吧???

(不得不diss下,多數(shù)抽獎(jiǎng)活動(dòng)大獎(jiǎng)概率設(shè)置的很低甚至為0,大獎(jiǎng)可謂是可望不可及,所以還是好好工作比較靠譜,寫bug,找bug,改bug? ? ???emm~)

總結(jié)

以上是生活随笔為你收集整理的天天福利抽奖-JAVA概率抽奖的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。