Because of the need of business, a lottery was held, and the winning prize was quite crooked.
But I still want to tell you secretly that the lottery is an insider ~ (can't be seen by the leaders, will be beaten)
Always see on various app s the turntable lottery, the doubling lottery, each time holding the heart of the biggest prize, in exchange for the hint of not winning the prize, it can be said that the bamboo basket is empty, repeated defeats, repeated defeats and repeated battles.~
Now let's talk about winning the prize. We have lined up with small benches to do a good job.
First, the realization of ideas (this should not be difficult to understand it ~)
Each prize has a corresponding winning probability. First, sum the winning probability of all prizes.
Calculate the interval blocks between 0 and 1 for each prize.
Random numbers between 0 and 1 are generated randomly. Which interval the random numbers fall in is the winning one.
For example, the following prizes are available:
The probability of winning prize A is 0.1.
The probability of winning prize B is 0.01.
The probability of winning prize C is 0.001.
The probability of winning prize D is 0.8.
Step 1: Find the sum of probabilities 0.1 + 0.01 + 0.001 + 0.8 = 0.911
Step 2: Calculate the area of each prize.
Prize A: 0.1/0.911 = 0.1098
Prize B: (0.1 + 0.01)/ 0.911 = 0.1207
Prize C: (0.1 + 0.11 + 0.001)/ 0.911 = 0.1218
Prize D: (0.1 + 0.11 + 0.001 + 0.8)/ 0.911 = 1
Then:
The range of prize A is 0-0.1098.
Prize B ranges from 0.1098 to 0.1207.
Prize C ranges from 0.1207 to 0.1218.
The range of prize D is 0.1218~1.
So far I should have understood the idea, but what I want to do is to upgrade this version.
Set the probability according to different types of people (emm~in other words, set the probability according to identity to distribute prizes)
Here's a note: Probability 10 represents 10%.
2. Dry goods are as follows
import lombok.Data; import lombok.ToString; /** * @Author: yansf * @Description:Reward entity * @Date:Creat in 10:35 AM 2019/1/16 * @Modified By: */ @Data @ToString public class RewardDto { /** * Prize id */ private int welfareId; /** * Welfare Management Id(Welfare_ManagerId) */ private int welfareMgrId; /** * Name of prize */ private String welfareName; /** * Prize type (game currency 10 vip trial 20 Tokyo card 30) */ private int welfareType; /** * Prize Quantity (Single Prize Limit) */ private int AwardCount; /** * Prize Value */ private int welfareValue; /** * Prize probability (10 for 10%) */ private int AwardPct; /** * Subprobabilities-class A probabilities */ private int APct; /** * Subprobability-Class B Probability */ private int BPct; /** * Subprobability-Class C Probability */ private int CPct; /** * Subprobabilities-class D probabilities */ private int DPct; /** * Remaining stock of prizes */ private int remainderAmount; /** * Prize Allocation Inventory */ private int totalAmount; }
/** * @Author: yansf * @Description:userType 1-A Human-like 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; //Getting Prize Configuration Information 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); } //Remove prizes with inventory of 0 list.removeIf(e -> e.getRemainderAmount() == 0); var firstReward = welfareMapper.getWelfareReceiveRecord(userId, null, null); //Have you won the vip trial in the past month or not? var vipTrial = welfareMapper.getvipTrialRecord(userId); //If it is already vip, VIP cannot be extracted if (isVip || vipTrial > 0) { list.removeIf(e -> e.getWelfareType() == 20); } //If the first lottery is drawn between events, the minimum probability of the lottery is 0. if (firstReward <= 0 && (list.size() >= 2)) { //Remove the configuration of the minimum prize 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) { //Total probability interval float totalPro = 0f; //Store new probabilistic intervals for each prize List<Float> proSection = new ArrayList<Float>(); DecimalFormat df = new DecimalFormat("######0.00"); int random = -1; try { //Calculate the total weight 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(); } } //Generating random numbers double randomNumber; randomNumber = Math.random(); //Determine the winning prize according to the random number in all prize distribution areas 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("Errors in generating random number of lottery draw, causes of errors:" + e.getMessage()); // throw e; } if (random != -1) { dto = list.get(random); } } if (dto == null) { dto = dto1; } return dto; }
/** * @Author: yansf * @Description:Lottery test * @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("The Draw Begins"); 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, "Game currency:" + coin + ",vip: " + vip + ",Jingdongka:" + jd, count); } else { return ResponseUtil.response(500, "Not winning the prize", count); } }
Here, 1000 cycles, using non-vipD people to do a test, the results are as follows
In fact, the probability lottery is very simple. If you want to divide the probability of the prize and set different probabilities according to different people, then multiply the proportion and add it up. For example:
//Calculate the total weight double sumWeight = 0; for (RewardDto award : list) { if (userType == 1) { //The probability of the prize here * the probability of different people drawing the prize sumWeight += award.getAPct()*avard.getPct(); } }
for (int i = 0; i < list.size(); i++) { if (userType == 1) { //Probability Multiplication 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; } }
See, you should learn it.