random()、对数器

random()、对数器

简介:当我们手写了一个排序算法后,往往手写几给数组进行测试。但这是小样本的测试不具有普遍性,这是就要采用对数器来生成大样本来检验算法。 对数器的作用:自动生成随机样本,让我们不再依赖线上测试也能完成算法的检验。实现:对数器依赖于random()随机函数,使得可以生成长度随机,值也随机的数组。

一、random() 随机函数

  1. 随机数函数"Math.random()":他会等概率返回[0,1)中间的一个随机数。

    //main方法
    public static void main(String[] args) {
            //1. random随机性测试
            System.out.println("randomTest(0.5) = " + randomTest(0.5));
          } 
    
    /**
         * random随机性测试
         *
         * @author lihaojie
         * @date 2022/12/10 10:56
         * @param max [0,max)
         * @return double
         */
        public static double randomTest(double max){
            //测试次数
            int testNumber =1000000;
            int count=0;
            for (int i = 0; i < testNumber; i++) {
                //如果生成的数小于max则count加1,否则不变
                count = (Math.random() < max) ? ++count : count;
    
            }
            return (double) count/testNumber;
        }
    
  2. random()往往只能生成[0,1)之间的double类型的小数,有时这不能满足我们于是对其改进。

    //main方法 
    public static void main(String[] args) {
           
            //2. randomPlus test
            for (int i = 0; i < 100; i++) {
                System.out.println("randomPlus(0) = " + randomPlus(9));
            }
            //3.xToxPower2 test
            int count=0;
            double x=0.5;
        	//测试10000次
            for (int i = 0; i <10000; i++) {  
                if (xToxPower2()<x) count++;
            }
        	//输出改进和的概率
            System.out.println("(double) count/10000 = " + (double) count / (double) 10000);
            //输出x^2的概率 
        	System.out.println("Math.pow(x,2) = " + Math.pow(x, 2));
        }
    /**
         * random改造,让其产生[0,multiple)随机整数
         *
         * @author lihaojie
         * @date 2022/12/10 11:08
         * @param multiple 倍数
         * @return int
         */
        public static int randomPlus(int multiple){
            return (int) (Math.random()*multiple);
        }
     /**
         * random是线性的,如何改造成x^2
         *
         * @return double
         * @author lihaojie
         * @date 2022/12/10 11:24
         */
        public static double xToxPower2() {
            /*
            为什么调用两个random再去最小值,就能实现x^2的效果呢?
            
            因为当调用两次random,它两个是独立的,可以看作两次独立重复实验,当两次结果的最大值还要小于x,则说明这两次都小于			x。我们知道random是等概率的,一次小于x=0.5的概率是p=1/2,那么在两次独立重复实验中同时小于x=0.5的概率则是 p^2
            */
            return Math.max(Math.random(), Math.random());
        }
    
  3. 经典面试题

    面试题1: f1()等概率随机产生1,2,3,4,5 。请利用f1()得到目标函数 goal() 使其随机产生1-7的整数

    // 面试题1: 给你一个f1(),可随机产生1,2,3,4,5。现在我让使用f1()构造一个f2()使得其随机产生1,2,3,4,5,6,7
    
    /*解析:
    	我们可用随机函数f1()构造一个随机种子函数,让其随机产生0,1。当我们得到随机种子函数,再将其改造成生成1-7的随机函数
    */
    //第一步:	利用f()函数构造0,1的随机种子函数f2()
     public static int f2(){
         /*我们知道f1()返回1,2,3,4,5的概率均是p=0.2 所以我们这个规定,当f1()返回1,2时对应0,4,5时对应1,3则重新调用f1()知道不在等于3为止。这样就等概率的返回0,1了*/
            int a;
            do {
                 a = f1();
            }while (a==3);
            return a<3 ? 0:1;
        }
    //第二步:	实现0-7等概率返回 
     public static int f3(){
         //调用1次f2()会产生两种结果,那么调用三次就会组合出8中结果,例如:000,001,010,…… ,111
         //而这恰好是0-7的所对应的二进制
            return (f2()<<2)+(f2()<<1)+(f2()<<0);
        }
    //第三步:	0-7 转换为 0-6等概率返回
     public static int f4(){
         /*f4()的思路与f2()相同,我们既然能随机生成0-7了,那我们将f3()>6时重新调用f3(),就可随机生成0-6*/
            int ans;
            do{
                ans=f3();
            }while (ans==7);
            return ans;
        }
    //第四步: 0-6 --转变-->1-7
     public static int goal(){
            return f4()+1;
        }
    

    面试题2:

    f1()不等概率产生0,1。f1()==0的概率为p,f1() ==1的概率为1-p。请利用f1()得到目标函数 goal() 使其随机产生1-7的整数。

    思路:我们调用两次f1()函数,其中00与11情况都不要(不要:再调用两次,直到结果不是这两个)。则10,01为将等概率出现,概率:p*(1-P)。我们规定10 -->0; 01–>1。这就找到了随机种子函数,可随机产生0,1。之后方法如上。

二、对数器

	public static void main(String[] args) {
    	 //对数器的使用
        for (int i = 0; i < testTimes; i++) {
            int maxLen=100;
            int maxValue=100;
            int[] arr1=arrRandom(maxLen,maxValue);
            int[] tmp = arr1.clone();
            insertSort2(arr1);
            //检测排序是否成功
            for (int j = 1; j < arr1.length; j++) {
                //保证相邻两个数之间,前一个数都小,才说明数组升序
                if (arr1[j-1]>arr1[j]){
                    System.out.println("出错了,出错数组为:");
                    for (int count1 = 0; count1 < tmp.length; count1++) {
                        System.out.print(tmp[count1]);
                    }
                    System.out.println("结果为:");
                    for (int count1 = 0; count1 < arr1.length; count1++) {
                        System.out.print(arr1[count1]);
                    }
                }
            }
        }
	}
/**
     * 对数器:返回一个arr,长度 ->[0,maxLen-1) arr中的每个值 -> [0,maxValue-1)
     *
     * @author lihaojie
     * @date 2022/12/10 15:08
     * @param maxLen 数组长度上限
     * @param maxValue  值上限
     * @return int[]
     */
    public static int[] arrRandom(int maxLen,int maxValue){
        int[] arr=new int[(int) (Math.random()*maxLen)];
        for (int i = 0; i < arr.length; i++) {
            arr[i]=(int) (Math.random()*maxValue);
        }
        return arr;
    }

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值