import org.junit.Test;
/**
-
@author luoz
-
@date 2021/6/27 0027 0:44
-
@description
*/
public class RandToRand2 {/**
- 一个随机生成min到max的函数
- @param max 随机生成的最大值
- @param min 随机生成的最小值
- @date 0:49 2021/6/27 0027
- @return int
**/
private int f1(int max,int min){
return (int)(Math.random()*(max-min+1))+min;
}
/**
- 生成任意区间随机数的方法
- @param max 生成区间的最大值
- @param min 生成区间的最小值
- @param rMax 原始生成随机数的函数(f1)的最大值
- @param rMin 原始生成随机数的函数(f1)的最小值
- @date 0:52 2021/6/27 0027
- @return int
**/
private int randM2M(int max,int min,int rMax,int rMin){
int count=max-min;
int k=1;
//获取大于等于count的最小数(这个数是2的冥次方)的二进制位数,
while ((count>>>=1)!=0){
k++;
}
int sum;
// 获取在该区间的返回值
do{
sum=0;
for(int i=0;i<k;i++){
// 获取大于等于count的最小二的冥次方数的随机值
sum+=(rzo(rMax,rMin)<<i);
}
// 淘汰掉大于最大值的随机值
}while (sum+min>max);
// 返回区间的值
return sum+min;
}
public int rzo(int max,int min){
int mid=(max-min+1)/2;
int d1=min+mid;
int d2=max-mid;
int r;
do{
// 获取一个区间的随机值,
r=f1(max,min);
//淘汰掉影响0,1分布为平均分布的随机值
}while (r>=d1&&r<=d2);
//返回一个0,1的二项分布,且1的概率为0.5
return r<d1?0:1;
}/**
-
测试方法
-
测试生成随机数的概率分布
-
@date 0:51 2021/6/27 0027
**/
@Test
public void test001(){
//设置存储生成随机数的数组
int[] arr=new int[1024];
int n=1000000;
for (int i=0;i<n;i++){
//调用生成随机数的方法
//该方法的含义是 由一个生成随机数的函数f1,只能生成rMax到rMin,这里是1-5,且每个数的生成概率相等
//由该f1函数得到 一个均匀分布的区间max到min,这里是21-20
int r=randM2M(35,13,5,1);;
arr[r]+=1;
}for(int i=0;i<arr.length;i++){
if(arr[i]!=0){
// 打印不为零的数字
System.out.println(i+" : "+1.0*arr[i]/n);
}
}
}
}