算法之Math.Random

题目:
1.从1-5随机到1-7随机
2.从a-b随机到c-d随机
3.01不等概率随机到01等概率随机
/**
     * 题目:从1-5随机到1-7随机
     * 思路:
     *  step1:利用f1函数得到一个 0,1等概率 f2函数
     *  step2:用3个二进制位表示,每个二进制位调用一个f2 得到 0~7等概率  f3 函数
     *  step3: 调用f3函数,如果得到7就重新调用,否则就返回 ,得到0~6等概率 f4 函数
     *  step4:f4函数加一
     * @return
     */
    //等概率随机返回1,2,3,4,5
    public static int f1(){
        return (int)Math.random()*5+1;
    }

    /**
     * 随机机制,只能用f1
     * 概率返回0和1
     * 思路:
     * 由于f1是等概率返回1,2,3,4,5 ,
     * 调用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;
     }

     //得到二进制位 000~111 做到等概率, 即 0~7等概率返回
     public static int f3(){
         int ans = (f2() << 2) + (f2() << 1)+ (f2() << 0);
         return ans;
     }

     //0~6等概率返回一个
     public static int f4(){
         int ans = 0;
         do{
             ans = f3();
         }while (ans == 7);
         return ans;
     }

     public static int g(){
         return f4()+1;
     }
同理可得出:

从a-b随机到c-d随机
思路:
 由 a-b 随机得到 0,1 等概率,即如果b-a+1 是奇数,则调该函数,如果得到前一半数字返回0,得到后一半数字返回1,得到中间的一个数则重新调,就得到了 0,1 等概率
 1.要得到c-d 随机,可以先得到 0-(d-c)随机,然后再加c,就得到了0-d 随机,
 2.要得到 0 - (d-c)随机 就要看需要几个二进制位了,1个二进制位可以得到0-2随机,两个二进制位可以得到0,3(2^0+2^1)随机,三个二进制位可以得到0,7(2^0+2^1+2^2)随机,·····
 3.然后做do,while 多余的部分,重新调,否则就返回,得到  0 - (d-c)随机
 4. 加c ,得到 c-d 随机
/**
     * 题目:01不等概率随机到01等概率随机 , 例如x()函数,以p概率返回0,以1-p概率返回1,
     * 思路:
     * 用两个二进制位表示,调用两次f()函数,如果得到00(概率是p*p),重新调,如果得到11(概率是(1-p)*(1-p))重新调,
     * 如果得到01(概率是p*(1-p))返回0,如果得到10(概率是(1-p)*p)返回1
     *  由于 01(概率是p*(1-p)) 和10(概率是(1-p)*p) 是等概率的,所以只在这两种情况返回0或1,其他情况则重新调
     *  例如有一个函数x(),你只知道,x会以固定概率返回0和1,但是x的内容,你看不到
     * @return
     */
     public static int x(){
         return Math.random() < 0.84 ? 0 : 1;
     }

     //等概率返回0和1
     public static int y(){
         int ans = 0;
         do {
             ans = x();
         }while (ans == x());
         return ans;
     }
任意的x,x属于[0,1),[0,1)范围内出现的数由原来的x调整成x的平方
/**
     * 返回[0,1)范围内的一个数
     * 任意的x,x属于[0,1),[0,1)范围内出现的数由原来的x调整成x的平方
     * @return
     */
    public static double xToXPower2(){
        return Math.max(Math.random(),Math.random());
    }

测试方法

public static void main(String[] args) {
        int testTimes = 10000000;
        int count = 0;
        for (int i = 0; i < testTimes; i++) {
            double ans = Math.random(); //产生[0,1)之间的数
            if(ans < 0.3) count++;
        }
        //System.out.println((double)count/(double)testTimes);


        //0~X 范围内 任意x出现的概率是X
        double x = 0.7;
        count = 0;
        for (int i = 0; i < testTimes; i++) {
            if(xToXPower2() < x) count++;
        }
        System.out.println((double)count/(double)testTimes);
        System.out.println(Math.pow(x,2));

        int[] counts = new int[8];
        for (int i = 0; i < testTimes ; i++) {
            int num = f3();
            counts[num]++;
        }
        for (int i = 0; i < 8; i++) {
            System.out.println(i+"这个数出现了 "+ counts[i] +"次");
        }

    


    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值