如果你也在找一个取得范围内随机数的算法,看看下面的介绍吧。
这次主要说一下Java中的随机数取得函数Random()。
以下为本次要介绍的取得范围内随机数的函数。
/***
* 取得范围内的随机数
* @param min
* @param max
* @return
*/
public static int getRandInteger(int min,int max) {
int rt = 0;
try {
Random random = new Random();
//方法一:
//rt= random.nextInt(max) % (max - min + 1) + min;
//方法二:
rt= random.nextInt(max-min+1) + min;
return rt;
} catch (Exception e) {
log.error("Get random error:", e);
return -1;
}
}
以上代码可见有两个方法,方法一是我从网上获得的其他网友的方法,这个方法确实也可以取得范围内的随机数。
测试类:
@Test
void getRandInteger() {
HashMap<Integer,Integer> map=new HashMap<Integer, Integer>();
int sum=0;
for(int i=0;i<1000;i++)
{
Integer r=RandomUtil.getRandInteger(10,40);
if(map.containsKey(r))
{
Integer counter=map.get(r)+1;
map.put(r,counter);
}else
{
map.put(r,1);
}
//System.out.println(RandomUtil.getRandInteger(8,40));
sum++;
}
map=(HashMap<Integer,Integer>)MapDataUtil.sortByKey(map,false);
map.forEach((k,v)->System.out.println("取得值:"+k.toString()+" --> \t
次数:"+v.toString()));
System.out.println("总计:"+sum);
}
但经过我测试,这个随机数并不随机,或者说随机的概率并不呈现一个均匀分布,这不是我想要的。
在范围(1,20)时,随机概率还算均匀,如下:
取得值:1 --> 次数:55
取得值:2 --> 次数:59
取得值:3 --> 次数:48
取得值:4 --> 次数:40
取得值:5 --> 次数:52
取得值:6 --> 次数:51
取得值:7 --> 次数:56
取得值:8 --> 次数:40
取得值:9 --> 次数:56
取得值:10 --> 次数:46
取得值:11 --> 次数:47
取得值:12 --> 次数:42
取得值:13 --> 次数:42
取得值:14 --> 次数:56
取得值:15 --> 次数:54
取得值:16 --> 次数:42
取得值:17 --> 次数:51
取得值:18 --> 次数:69
取得值:19 --> 次数:51
取得值:20 --> 次数:43
总计:1000
但是如果是范围不是从1开始的,如(10,30),结果就不同了,如下:
取得值:10 --> 次数:50
取得值:11 --> 次数:48
取得值:12 --> 次数:48
取得值:13 --> 次数:43
取得值:14 --> 次数:48
取得值:15 --> 次数:48
取得值:16 --> 次数:70
取得值:17 --> 次数:55
取得值:18 --> 次数:47
---------分割线-------
取得值:19 --> 次数:20
取得值:20 --> 次数:27
取得值:21 --> 次数:38
取得值:22 --> 次数:26
取得值:23 --> 次数:25
取得值:24 --> 次数:29
取得值:25 --> 次数:21
取得值:26 --> 次数:26
取得值:27 --> 次数:24
取得值:28 --> 次数:27
取得值:29 --> 次数:16
取得值:30 --> 次数:26
取得值:31 --> 次数:28
取得值:32 --> 次数:20
取得值:33 --> 次数:20
取得值:34 --> 次数:19
取得值:35 --> 次数:28
取得值:36 --> 次数:27
取得值:37 --> 次数:30
取得值:38 --> 次数:19
取得值:39 --> 次数:26
取得值:40 --> 次数:21
总计:1000
从上面结果可知,从10-18这个范围取得的概率远大于其他数取得的概率。
这也不是正常意义下的取得随机数,如果程序严谨的话,这是不符合要求的(我又开始认真了.....)
经过我反复测试研究,发现这并不是偶然,如果取数范围为(min,max),那么(min,min+min-1)这个范围内的数取得的概率是远大于其他数的。
这个结果如果你的程序只是要个随机数,概率不要求平均,那这个取得方法是没有问题的,
但在某些情况下,比如我要用的场景,不但要取得一个范围的数,还需要概率趋于平均,那就不能用方法1了。
介绍一下方法2:
//方法二:
random.nextInt(max-min+1) + min;
方法2的原理其实是取得【0,max-min】这个范围内的随机数,这个方式,在上面的测试中已经证实还是比较平均的,那如果最小值不是0,那就手动给它+min即可。
看下测试结果:
取得值:10 --> 次数:35
取得值:11 --> 次数:40
取得值:12 --> 次数:31
取得值:13 --> 次数:29
取得值:14 --> 次数:46
取得值:15 --> 次数:38
取得值:16 --> 次数:33
取得值:17 --> 次数:18
取得值:18 --> 次数:30
取得值:19 --> 次数:35
取得值:20 --> 次数:21
取得值:21 --> 次数:41
取得值:22 --> 次数:26
取得值:23 --> 次数:31
取得值:24 --> 次数:28
取得值:25 --> 次数:31
取得值:26 --> 次数:45
取得值:27 --> 次数:35
取得值:28 --> 次数:21
取得值:29 --> 次数:26
取得值:30 --> 次数:27
取得值:31 --> 次数:39
取得值:32 --> 次数:31
取得值:33 --> 次数:37
取得值:34 --> 次数:42
取得值:35 --> 次数:26
取得值:36 --> 次数:36
取得值:37 --> 次数:32
取得值:38 --> 次数:27
取得值:39 --> 次数:30
取得值:40 --> 次数:33
总计:1000
第二次测试运行结果:
取得值:10 --> 次数:31
取得值:11 --> 次数:32
取得值:12 --> 次数:30
取得值:13 --> 次数:27
取得值:14 --> 次数:34
取得值:15 --> 次数:27
取得值:16 --> 次数:26
取得值:17 --> 次数:33
取得值:18 --> 次数:30
取得值:19 --> 次数:45
取得值:20 --> 次数:33
取得值:21 --> 次数:37
取得值:22 --> 次数:34
取得值:23 --> 次数:47
取得值:24 --> 次数:34
取得值:25 --> 次数:39
取得值:26 --> 次数:35
取得值:27 --> 次数:32
取得值:28 --> 次数:29
取得值:29 --> 次数:25
取得值:30 --> 次数:37
取得值:31 --> 次数:37
取得值:32 --> 次数:37
取得值:33 --> 次数:30
取得值:34 --> 次数:27
取得值:35 --> 次数:31
取得值:36 --> 次数:28
取得值:37 --> 次数:29
取得值:38 --> 次数:30
取得值:39 --> 次数:35
取得值:40 --> 次数:19
总计:1000
两次运行的结果还是比较平均的吧,第一个方法网上说的比较多,应该是在取模的时候造成了分布不均,
方法二其实更简单易懂,使用起来也方便,个人认为还是不错的,如果你有更好的算法,欢迎告知。
简码笔记,让你的代码更加简约精炼。
转载请注明出处。