java 百分比概率计算,JAVA实现概率计算(数字不同范围按照不同几率产生随机数)-站长资讯中心...

c4468b3f4df77e96b0a416fa2a870fba.png

程序中经常遇到随机送红包之类的情景,这个随机还得指定概率,比如10%的机率可以得到红包。那么java怎么实现一个简单的概率计算了,见如下例子:

int randomInt = RandomUtils.nextInt(1,101);if(randomInt <= 10){ //100里面1个数,小于等于10的概率就是10%//do something

}

RandomUtils工具类是commons-lang3包里面的

org.apache.commons

commons-lang3

3.7

如果要在某个数字区间产生一个随机数,区间内部在不同的片段几率不同如何实现呢?经常有这样的场景,比如,随机赠送红包,范围0.1元-100元,0.1-1元的概率是90%,1元-10元的概率是9%,10元-100元的概率是1%,也就是说数额越大得到的几率越小!实现的原理如下图:

af327587fc4b03b91bcdf5c077115194.png

原理就是,将范围分割成一个个子范围(片段),具体采用哪个范围,再用机率判断。片段机率可以依次排好序,映射成[1,100]之间的数字。然后随机一个[1,100]之间的数,该数落在哪个区间,就采用哪个片段产生随机数。具体源代码如下:

packagecom.hdwang;importorg.apache.commons.lang3.RandomUtils;importjava.util.ArrayList;importjava.util.List;/*** 按几率产生随机数

* 例如,产生0.1-100的随机数,0.1-1的几率是90%,1-10的几率是9%,10-100的几率是1%*/

public classRateRandomNumber {/*** 产生随机数

*@parammin 最小值

*@parammax 最大值

*@return随机结果*/

public static double produceRandomNumber(double min,doublemax){return RandomUtils.nextDouble(min,max); //[min,max]

}/*** 按比率产生随机数

*@parammin 最小值

*@parammax 最大值

*@paramseparates 分割值(中间插入数)

*@parampercents 每段数值的占比(几率)

*@return按比率随机结果*/

public static double produceRateRandomNumber(double min,double max,List separates,Listpercents){if(min >max){throw new IllegalArgumentException("min值必须小于max值");

}if(separates == null || percents==null || separates.size()==0){returnproduceRandomNumber(min,max);

}if(separates.size() +1 !=percents.size()){throw new IllegalArgumentException("分割数字的个数加1必须等于百分比个数");

}int totalPercent = 0;for(Integer p:percents){if(p<0 || p>100){throw new IllegalArgumentException("百分比必须在[0,100]之间");

}

totalPercent+=p;

}if(totalPercent != 100){throw new IllegalArgumentException("百分比之和必须为100");

}for(doubles:separates){if(s <= min || s >=max){throw new IllegalArgumentException("分割数值必须在(min,max)之间");

}

}int rangeCount = separates.size()+1; //例如:3个插值,可以将一个数值范围分割成4段//构造分割的n段范围

List ranges = new ArrayList();int scopeMax = 0;for(int i=0;i

Range range= newRange();

range.min= (i==0 ? min:separates.get(i-1));

range.max= (i== rangeCount-1 ?max:separates.get(i));

range.percent=percents.get(i);//片段占比,转换为[1,100]区间的数字

range.percentScopeMin = scopeMax +1;

range.percentScopeMax= range.percentScopeMin + (range.percent-1);

scopeMax=range.percentScopeMax;

ranges.add(range);

}//结果赋初值

double r =min;int randomInt = RandomUtils.nextInt(1,101); //[1,100]

for(int i=0;i

Range range=ranges.get(i);//判断使用哪个range产生最终的随机数

if(range.percentScopeMin <= randomInt && randomInt <=range.percentScopeMax){

r=produceRandomNumber(range.min,range.max);break;

}

}returnr;

}public static classRange{public doublemin;public doublemax;public int percent; //百分比

public int percentScopeMin; //百分比转换为[1,100]的数字的最小值

public int percentScopeMax; //百分比转换为[1,100]的数字的最大值

}public static voidmain(String[] args) {

List separates = new ArrayList();

separates.add(1.0);

separates.add(10.0);

List percents = new ArrayList();

percents.add(90);

percents.add(9);

percents.add(1);for(int i=0;i<100;i++) {double number = produceRateRandomNumber(0.1, 100, separates, percents);

System.out.println(String.format("%.2f",number));

}

}

}

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值