zoukankan      html  css  js  c++  java
  • [算法]由random(0,1)生成random(a,b)

    问题描述:

    描述RANDOM(a,b)过程的一种实现,它只调用RANDOM(0,1)。作为a和b的函数,你的程序期望运行时间是多少?

    这是算法导论上的一道题。

    这个没有固定答案,看了很多网上的解法之后,总结一下我的想法。首先,random(0,1)是随机的产生0,1两个整数,random(a,b)是随机产生[a,b]之间的整数。随机就是等概率的意思。生成random(a,b)等价于随机生成[0,b-a]内的一个数,然后在加上a就是[a,b]之间的数了。

    解法一:

    设k=b-a,假设2的c次方(以下用2^c表示)是第一个大于b-a的2的正整数次方,那么调用random(0,1)c次,产生一个c位的二进制数,对应一个[0,2^c-1]的十进制数,如果这个数在[0,b-a]之内,输出,否则继续生成c位二进制数,直到得到一个[0,b-a]之内的数为止。

    下面是java代码的表示:

    public int randomAB2(int a,int b){
            int k=b-a;
            //找到第一个2^n大于k的n
            int k1=k;
            int c=0;
            while(k1!=0){
                c++;
                k1=(int)Math.floor(k1/2);
            }
            int s=0;
            //生成0到k的数
            do{
                s=0;
                for(int i=0;i<c;i++){
                    s+=random01()*Math.pow(2, i);
                }
            }
            while(s>k);
            return s+a;
        }

    期望运行时间:

    第二个while循环的运行次数呈几何分布,每一次成功(也就是得到了[0,b-a]之内的数)的概率是---p=(b-a+1)/(2^c),这里的c应该是lg(b-a)向上取整,所以运行次数的期望是Tavg=1/p。

    期望运行时间T(a,b)=Tavg*lg(b-a)*D。其中lg(b-a)是以2为底b-a的对数,D是第二个while循环内代码运行的时间,是个常数。这个貌似是个O(lg(b-a))级别的运行时间。

    解法二:

    这个方法来自http://blog.csdn.net/longhuihu/article/details/5864442这篇博文的解法一。这个方法也是先生成一个长度为k=b-a+1二进制序列---R1,R2,..,然后把二进制序列中值为0对应的[0,b-a]中的数删除,从而减小要生成数的范围。

    下面是模拟这个过程的java代码:

    View Code
    public int randomAB(int a,int b){
            int k=b-a+1;
            ArrayList<Integer> S=new ArrayList<Integer>();
            ArrayList<Integer> temS;
            for(int i=0;i<k;i++){
                S.add(i);
            }
            temS=copy(S);
            while(S.size()>1){
                int n=S.size();
                for(int j=n-1;j>=0;j--){
                    int r=random01();
                    if(r==0){
                        temS.remove(j);
                    }
                }
                if(temS.isEmpty()){
                    temS=copy(S);
                }
                else{
                    S=temS;
                    temS=copy(S);
                }
            }
            return S.get(0)+a;
        }

    这个理解起来比较容易,但是分析期望运行时间比较复杂。

    首先,要生成几次b-a+1长度的二进制序列才能达到缩减范围的目的?这也是个几何分布,每次试验成功的概率是p=1-2/2^k(因为只要不生成全0或全1就会成功)。那么试验次数的期望是Tavg=1/p。那么运行时间T(a,b)可以表示为T(a,b)=Tavg*k*D+T(x)。这个T(x)表示任何可能的缩小范围后的范围,x取值在1-(k-1)之间,D是循环内的常数运行时间。

    这篇文章证明了这种做法最后输出的a,b之间的数肯定是等概率的,应用了数学归纳法,证明方法如下:

    (1)能够等概率生成0,1

    (2)假设有random(m),m<k等概率生成0-m之间的数。

    (3)证明random(k)生成[0,k-1]之间的数也是等概率的:

    定义事件:

    Ai--输出第i个数

    Bim--一轮筛选后m个数留下,其中包含第i个数

    P(Ai|Bim)=random(m)=1/m,这是(2)的假设。

    P(Ai,Bim)=P(Bim)*P(Ai|Bim)=P(Bim)*(1/m)。

    P(Bim)=C((k-1),(m-1))/(2k-2)。C((k-1),(m-1))是个组合公式。

    P(Ai)=∑P(Ai,Bim) for m=1:(k-1)。这是个求和公式,对m从1到k-1取值求和。

    求解后的P(Ai)=1/k。

  • 相关阅读:
    vue——样式穿透/deep/ >>> ::v-deep 三者的区别
    CSS Grid 网格布局教程
    CSS3中的display:grid网格布局介绍
    windows 好用的命令
    django分页
    django.template.exceptions.TemplateSyntaxError: 'staticfiles' is not a registered tag library. Must
    bootstrap模板
    django报错 django.core.exceptions.ImproperlyConfigured: mysqlclient 1.4.0 or newer is required; you have 0.10.1
    bootstrapV4.4.1版本下载
    Dots demo解释相关
  • 原文地址:https://www.cnblogs.com/orchid/p/3019433.html
Copyright © 2011-2022 走看看