目录
一.随机函数
1.Math.random()
Math.random()是等概率生成double类型数据的函数,且生成数在[0,1)的区间内
2.验证生成数是等概率的
(1)假设函数生成0~1的数都是等概率的,那么在0~1内的任何数的大小都应该与其大小相等,例如进行10000次生成数,那么生成0.3这个数的频率应约等于其概率,也为0.3
(2)于是我们定义一个count=0,进行10000次随机生成,令其每进行一次随机生成数 <0.3时就让count++,最后把count除以总次数就是0.3这个数生成的频率
(3)代码如下
//Math.random()->[0,1)
public static void Exam() {
int textTimes = 10000;
int count = 0;
for (int i = 0; i < textTimes; i++) {
if (Math.random() < 0.3)
count++;
}
System.out.println((double) count / (double) textTimes);
System.out.println("===================");
可以发现其大小约等于0.3,说明该函数生成数是等概率的
3.验证该函数可以进行乘法运算
(1)假设该函数可以进行乘法运算,那么说明之前从[0,1)的取值范围,如果×8的话,取值范围将变成[0,8)
(2)我们假设×8之后的数,如果小于4的概率约等于0.5,那么假设成立
(3)代码如下
//Math.random() * 8->[0,8)(double)
count = 0;
for (int i = 0; i < textTimes; i++) {
if (Math.random() * 8 < 4)
count++;
}
System.out.println((double) count / (double) textTimes);
//约等于0.5
System.out.println("===================");
所以说明该函数是可以进行乘法运算的
4.检验其是否可以随机生成整数
(1)假设将函数强制进行(int)类型转换,并且假设函数*k,那么取值范围就是[0,k-1],的随机整数
(2) 我们可以通过检查0~k-1的每个整数出现的次数是否大致相等来推断是否等概率出现
(3)我们可以建立一个counts[k]数组,记录0~k-1每个数出现的次数然后打印
int k = 9;
//int 型
//Math.random()->[0,k)->[0,8]
count = 0;
int counts[];
counts = new int[k];
for (int i = 0; i < textTimes; i++) {
int ans = (int) (Math.random() * k);
counts[ans]++;
}
for (int i = 0; i < k; i++) {
System.out.println(i + "这个数出现了" + counts[i] + " 次");
//每个数出现次数差不多
}
System.out.println("===================");
可以看到,生成次数大致相等
5.如何把获得的x[0,x)的概率变成x平方
(1)我们调用两次随机函数,使之得到结果都能保证两次被调用
(2)使用Math.max()函数,使Math.max(Math.random(),Math,random)<x;
为何是max呢?
因为要保证两次函数都被调用,所以Math.max()括号里的两个值都小于x时就能实现,如果是min,那一个小于x就实现了
public static double xtoXpower2() {
return Math.max(Math.random(), Math.random());
//注意是取最大值
}
二.应用题目
1.如何用1~5的随机函数加工出1~7的随机函数
(1)有一个f ()函数能够实现1~5的随机数
//f1()函数,题目所给,能够实现1~5随机
public static int f1() {
return (int) (Math.random() * 5) + 1;
}
(2)写一个f2()函数变成0,1发生器
在f1的基础上,如果生成1,2那么返回0;如果生成4,5那么返回1,生成3则重做
public static int f2() {
int ans = 0;
do {
ans = f1();
} while (ans == 3);
return ans < 3 ? 0 : 1;
}
(3)写一个f3()函数实现0~7随机
既然我们得到了0,1发生器,那么我们可以用二进制的方式取得任何范围的随机数
这里我们想得到0~7随机,那么就用三位二进制就可以实现
于是我们返回f2分别向左移动两位、一位、零位
//写一个f3()函数,实现0~7随机
public static int f3() {
return ((f2() << 2) + (f2() << 1) + f2());
}
(4)写一个g()函数实现1~7随机
有了f3,那么根据之前的证明得到1~7的g函数就直接在f3()==0的时候重做就好啦
public static int g() {
int ans = 0;
do {
ans = f3();
} while (ans == 0);
return ans;
}
2.如何把不等概率随机函数变成等概率随机函数
有一个x()函数,使x函数能够发生0和1 的概率不相等
public static int x() {
return Math.random() < 0.84 ? 0 : 1;
}
我们可以调用两次x(),虽然同时为0或者同时为1的情况不相等,但是第一次为0第二次为1与第一次为1第二次为0的概率是相等的
于是代码如下
//写一个y()函数,使x()函数能够发生0和1的概率相等
public static int y() {
int ans = 0;
do {
ans = x();
} while (ans == x());
return ans;
}
验证也是对的