欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【功能实现】实现设置概率的随机数

程序员文章站 2022-05-04 10:52:54
1.故事背景 生成一个随机红包,红包的数值0.1元-100元不等,其具体概率为:0.1元为最小单位,0.1元到0.5元的概率为40%,0.5元到1元的概率为50%,1元-2元的概率为5%,2元-3元的概率为3%,3元-4元的概率为1%,4元-5元概率为0.99%,5元-100元的概率为0.01%。 ......

1.故事背景

  生成一个随机红包,红包的数值0.1元-100元不等,其具体概率为:0.1元为最小单位,0.1元到0.5元的概率为40%,0.5元到1元的概率为50%,1元-2元的概率为5%,2元-3元的概率为3%,3元-4元的概率为1%,4元-5元概率为0.99%,5元-100元的概率为0.01%。

2.思考过程

  其实问题很简单,把概率放到一条线段上,我们先把问题简单化,假设随机生成0的概率是40%, 生成1的概率是50%,生成2的概率为5%,生成3的概率是3%...,线段上的0.4/0.9/0.95都是计算上两个概率后的和,那么如果我们此时生成一个随机数n,他的随机 的区间是0到1,如果生成0.2,那么就会落到0-0.4的概率区间中,如果是0.7就是 0.4-0.9的概率区间中,符合问题逻辑。

  【功能实现】实现设置概率的随机数

3.实现方式

  回到刚开始的故事,就是把第一层的概率逻辑拿过来,然后具体区间中生成的红包数额再进行一次随机数的生成,所以我设计了一个CommonRandom类来存放红包区间的最小值和最大值,还有个该区间的概率,

  CommonRandom类

 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

   生成randomUtil

 8 /**
 9  * @author wangjun
10  * @Date 2018/3/6
11  */
12 public class RandomUtil {
13     /**
14      * 保留小数位数
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      * 返回指定概率生成的随机数
30      * 传入集合中的chance概率和应为1
31      * @param commonRandomList 配置生成随机数概率及区间
32      * @return 随机数
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 }