1. Story background
A random red packet is generated. The value of the red packet varies from 0.1 yuan to 100 yuan. The specific probability is: 0.1 yuan is the minimum unit, the probability of 0.1 yuan to 0.5 yuan is 40%, the probability of 0.5 yuan to 1 yuan is 50%, the probability of 1-2 yuan is 5%, the probability of 2-3 yuan is 3%, the probability of 3-4 yuan is 1%, the probability of 4-5 yuan is 0.99%, and the probability of 5-100 yuan is 0.01%.
2. Thinking process
In fact, the problem is very simple. Put the probability on a line segment. Let's simplify the problem first. Suppose that the probability of randomly generating 0 is 40%, the probability of generating 1 is 50%, the probability of generating 2 is 5%, and the probability of generating 3 is 3%. 0.4/0.9/0.95 on the line segment is the sum of the two probabilities, If we generate a random number n at this time, its random interval is 0 to 1. If we generate 0.2, it will fall into the probability interval of 0-0.4. If it is 0.7, it will fall into the probability interval of 0.4-0.9, which is in line with the problem logic.
3. Implementation mode
Back to the beginning of the story, I took the probability logic of the first layer, and then generated a random number for the amount of red packets generated in the specific interval. So I designed a CommonRandom class to store the minimum and maximum values of the red packet interval, as well as the probability of the interval,
CommonRandom class
8 /** 9 * @author wangjun 10 * @Date 2018/3/6 11 */ 12 public class CommonRandom { 13 private Double min; 14 private Double max; 15 private Double chance; 16 private Double calculateRate; 17 18 private transient Integer reality = 0; 19 private transient Double realityRate; 20 21 public static CommonRandom getInstance(Double min, Double max, Double rate) { 22 CommonRandom commonRandom = new CommonRandom(); 23 commonRandom.setMin(min); 24 commonRandom.setMax(max); 25 commonRandom.setChance(rate); 26 return commonRandom; 27 } 28 29 public static String getDefault() { 30 return JsonUtils.toJson(getCommonRandom()); 31 } 32 33 public Double getMin() { 34 return min; 35 } 36 37 private void setMin(Double min) { 38 this.min = min; 39 } 40 41 public Double getMax() { 42 return max; 43 } 44 45 private void setMax(Double max) { 46 this.max = max; 47 } 48 49 public Double getChance() { 50 return chance; 51 } 52 53 private void setChance(Double chance) { 54 this.chance = chance; 55 } 56 57 public Double getCalculateRate() { 58 return calculateRate; 59 } 60 61 public void setCalculateRate(Double calculateRate) { 62 this.calculateRate = calculateRate; 63 } 64 65 public Integer getReality() { 66 return reality; 67 } 68 69 public void setReality(Integer reality) { 70 this.reality = reality; 71 } 72 73 public Double getRealityRate() { 74 return realityRate; 75 } 76 77 public void setRealityRate(Double realityRate) { 78 this.realityRate = realityRate; 79 } 80 81 private static List<CommonRandom> getCommonRandom() { 82 List<CommonRandom> commonRandomList = Lists.newArrayList(); 83 commonRandomList.add(CommonRandom.getInstance(0.1, 0.5, 0.4)); 84 commonRandomList.add(CommonRandom.getInstance(0.5, 1.0, 0.5)); 85 commonRandomList.add(CommonRandom.getInstance(1.0, 2.0, 0.05)); 86 commonRandomList.add(CommonRandom.getInstance(2.0, 3.0, 0.03)); 87 commonRandomList.add(CommonRandom.getInstance(3.0, 4.0, 0.01)); 88 commonRandomList.add(CommonRandom.getInstance(4.0, 5.0, 0.0099)); 89 commonRandomList.add(CommonRandom.getInstance(5.0, 100.0, 0.0001)); 90 return commonRandomList; 91 } 92 } 93 94 CommonRandom
Generate randomUtil
8 /** 9 * @author wangjun 10 * @Date 2018/3/6 11 */ 12 public class RandomUtil { 13 /** 14 * Keep decimal places 15 */ 16 private static final int POW = (int) Math.pow(10, 3); 17 private static final double ERROR_RANDOM_RESULT = -1D; 18 19 public static Double randomRedPackMoney() { 20 List<CommonRandom> commonRandoms = CommonRandom.getCommonRandom(); 21 Double result = random(commonRandoms); 22 if (result == ERROR_RANDOM_RESULT) { 23 return 1; 24 } 25 return result 26 } 27 28 /** 29 * Returns the random number generated by a specified probability 30 * The sum of chance probabilities in the incoming set should be 1 31 * @param commonRandomList Probability and interval of random number generated by configuration 32 * @return random number 33 */ 34 public static Double random(List<CommonRandom> commonRandomList) { 35 if (CollectionUtils.isEmpty(commonRandomList)) { 36 return ERROR_RANDOM_RESULT; 37 } 38 double randomNumber = Math.random() * getLastRate(commonRandomList); 39 for (CommonRandom item : commonRandomList) { 40 if (randomNumber < item.getCalculateRate()) { 41 return getRandomNumber(item.getMax(), item.getMin()); 42 } 43 } 44 return ERROR_RANDOM_RESULT; 45 } 46 47 private static double getLastRate(List<CommonRandom> commonRandomList) { 48 return commonRandomList.get(commonRandomList.size() - 1).getCalculateRate(); 49 } 50 51 private static Double getRandomNumber(Double max, Double min) { 52 return Math.floor((Math.random() * (max - min) + min) * POW) / POW; 53 } 54 }