随机函数及其应用

目录

一.随机函数

1.Math.random()

2.验证生成数是等概率的

3.验证该函数可以进行乘法运算

4.检验其是否可以随机生成整数

5.如何把获得的x[0,x)的概率变成x平方

二.应用题目

1.如何用1~5的随机函数加工出1~7的随机函数

2.如何把不等概率随机函数变成等概率随机函数


一.随机函数

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;
    }

验证也是对的

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值