用random(0,1)来实现random(a,b),并估计运行时间.

简介:

假设Random(a,b)以相同概率返回a到b之间的任何一个数字,描述Random(a,b)过程的一种实现,它只调用现有实现Random(0,1)。作为a和b的函数,你的程序的期望运行时间是多少?假设Ramdom(0,1)的运行时间是常数。

 

想到一种解法,分治法:
     1.分解,将a-b区间分成2部分,通过random(0,1)控制,则进入前半部和后半部的概率是一样的;
     2.递归的处理前后两个部分,若问题足够小,即落到某个具体位置上时,则直接返回;

伪代码:
int random( a, b )
{
   if( a == b )
     return a;
   if( random( 0, 1 ) )
     return random( a, (a+b)/2 );
   else
     return random( (a+b)/2 + 1, b );
}

但仔细分析下发现有问题.

令 n = b-a, 问题简化为 1/n = f( 1/(2^x) ), 
                root
                 / \
                0    1
               / \   / \
             /   .....   \
            0 .........  1
时间复杂度为 O(lgn),通过lgn次random(0,1)调用,即生成长度为lg(b-a)的"前后后前..."随机序列来控制最后落定的位置,类似2叉决策树的决策过程,x次random(0,1)调用最多可能产生2^x条路径,即最多可能返回2^x种结果,每条路径的产生概率相等,即1/(2^x).

但如果n不是2的整数次方,不可能将概率平均分配到每条路径,所以不可能在有限次调用内生成精确的平均返回概率.

如, n=8时,可以取x=3,正好8种返回结果的概率一样,都是1/8.但如果n=7,那么b的返回概率可能会是2/8,其余值的返回概率均为1/8.就不是相同的概率了,要想是等概率则n=2^x。
  

 

思路1:

这个题目相当于在能随机生成 0, 1 的前提下,要求随机生成 n 个整数。(每个数生成的概率相等)
把要生成的数标记为 0,1,2,..., n-1
取最小的 m,使得 2^m >= n-1(二分法分m次后每等分里面只有一个
通过随机生成 0,1 的函数生成一个  m 比特整数(随机生成每一位),这样能随机生成 [0, 2^m) 内的整数。
随机生成一个 [0,2^m) 中的整数,如果这个数大小在 [0,n-1] 内,则取这个数为结果。
如果这个数在 [0,n-1] 外,则丢弃它,重新生成一个。


思路2:

k = b-a+1,如果k为偶数,则将S均分成两组,通过一次R(0,1)来淘汰其中一组;如果S为奇数, 则用上述方法来分组,将占多数的一组淘汰。可以证明这个算法后也是正确的。只要在某一轮的测试中R(0,1)的输出为全0或全1,问题的规模就可以缩小一 半。

思路3:

或者用二分的方式,根据Ramdom(0,1)是0还是1进入[a,b]区间的前半部分或者后半部分,这样同样面临如果区间长度不是2的整数次方,会导致每个数生成的概率不一样,应该再做一点处理,扩大生成的范围,像思路1中把不是范围内的数丢掉。

 

 

在在没看答案之前 自己想了个方法:
  random(a,b)
{
  temp = a;
  while(i=0;i<=b-a;i++)
  {
  temp += random(0,1);
  }

  return temp;

}

我的个人感觉这个temp的概率也是1/(b-a+1); 大家的意见呢? 没找到数学方法证明对错

 

最开始的想到的是一个错误的算法,运行RANDOM(0,1)(b-a+1)次,然后将运行的结果累加,然后加上a得到最后的结果。
我感觉这也是很多人对这个问题的最直观的想法。
假设在运行RANDOM(0,1)(b-a+1)次中每次的结果形成一个序列,那么这个序列的和会重复,并且每一种结果重复的次数还是不一样的,所以导致了该算法的结果不对。
如果控制每一种和的序列只产生一次,那么这样就可以实现等概率分布了。
我的想法是将所有产生的序列控制为下面的形式:
000......001
000......011
000......111
............
............
............
001......111
011......111
111......111
以上是一个(b-a+1)阶的矩阵。
我现在的算法是只产生这个矩阵中每一行这种形式的序列。然后将这一行的结果进行相加。然后加上(a-1)得到最后的结果。
在这个矩阵的序列中有一个规律就是只要序列的某位为1,那么后面的元素都为1。

下面是伪代码(可能不是很规范,要是不明白的地方我马上补充)
Random(a,b)
//A是长度为b-a+1的数组,用来存储生成的序列
//i用来控制循环,也作为数组的标,temp用来存储每次random(0,1)生成的结果,
//test用来检测random(0,1)第一次生成的时候,一旦random(0,1)得到了1,那么以后的random(0,1)就只能得到1这个结果
//得到0的就舍弃并继续循环,直到得到特定形式的序列
A=new array(b-a+1); 
let i=1,temp=0,test=false; 
while(i<=b-a+1)
temp=RANDOM(0,1)
if test == true and temp == 0
continue;
if test== false and temp =1
test = true;
A[i] = temp;
i = i+1;
return a-1+sum(A)

再次感谢。
--------------------------------------------------------------------------------------------------
----------------------------------------------自己的改进方法----------------------------------------------------
谢谢Xi Yang的解答。根据他的回答,我修改了算法的实现过程。
主要是在利用多次循环来粗暴的找到所需的序列,而不是在一次循环中控制每次随机生成的结果
下面是伪代码(可能不是很规范,要是不明白的地方我马上补充)
Random(a,b)
//A是长度为b-a+1的数组,用来存储生成的序列
//i用来控制循环,也作为数组的标,temp用来存储每次random(0,1)生成的结果,
//test用来检测random(0,1)第一次生成的时候,一旦random(0,1)得到了1,那么以后的random(0,1)就只能得到1这个结果,这时将test赋值真
//在后面中如果random(0,1)得到0的就舍弃并重新开始循环,直到得到特定形式的序列
A=new array(b-a+1); ; 
let i=1,temp=0,test=false; 
while(true)
{
i=1
while(i<=b-a+1)
{
temp=RANDOM(0,1)
if test == true and temp == 0
break;
if test== false and temp =1
test = true;
A[i] = temp;
i = i+1
}
}
return a-1+sum(A)

再次感谢。



本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/4460483.html,如需转载请自行联系原作者

相关文章
|
算法 安全 数据挖掘
如何更轻松地学习差分隐私——《动手学差分隐私》中文版正式发布!
2022年10月28日,阿里巴巴集团数据技术及产品部DataTrust团队成员刘巍然、李双为差分隐私在线书籍《动手学差分隐私(Programming Differential Privacy )》提供的中文翻译版本正式被原著作者Joseph P. Near和Chiké Abuah合并到书籍GitHub仓库(https://github.com/uvm-plaid/programming-dp/)中
3026 0
如何更轻松地学习差分隐私——《动手学差分隐私》中文版正式发布!
|
存储 JSON 安全
从入门到精通:Python中的OAuth与JWT,打造无懈可击的认证体系🔒
【8月更文挑战第4天】构建现代Web和移动应用时,用户认证与授权至关重要。Python集成OAuth和JWT技术,能轻松实现安全认证。本文从OAuth基础入手,介绍如何使用`requests-oauthlib`库简化流程,再到JWT进阶应用,利用`PyJWT`库生成及验证令牌。最后,探讨如何结合两者,创建无缝认证体验。通过代码示例,由浅入深地引导读者掌握构建坚固应用认证体系的方法。
452 2
|
机器人 PHP
QQ云端机器人登录系统php源码
QQ云端机器人登录系统php源码
1165 4
|
量子技术
量子计算与教育:培养下一代量子科学家
在21世纪科技浪潮中,量子计算正从理论走向实践,深刻影响科学研究、工业制造、信息安全等领域。本文探讨量子计算与教育的结合,旨在培养具备量子思维和创新能力的下一代科学家,为未来科技创新奠定基础。通过课程革新、跨学科教育、实践平台搭建及国际化视野培养等策略,激发学生兴趣,提供丰富教育资源,强化实践与团队协作,推动量子科学的发展。
|
搜索推荐 数据挖掘 API
阿里巴巴API接口对电商的影响与收益
在全球电子商务快速发展的背景下,阿里巴巴作为领先的B2B平台,为中小企业提供商品批发、分销、供应链管理等一站式服务,并通过开放的API接口为开发者和电商企业提供数据资源与功能支持。本文将深入解析阿里巴巴API接口的功能(如商品搜索、详情、订单和用户管理)、应用(如商品展示、搜索优化、交易管理和用户行为分析)、收益(如流量增长、销售提升、库存优化)及实际案例,附带代码示例,助力电商从业者提升运营效率和用户体验。
439 0
|
机器学习/深度学习 人工智能 自然语言处理
【AI系统】AI的领域、场景与行业应用
本文概述了AI的历史、现状及发展趋势,涵盖AI系统的初步设计原则,并深入探讨了AI在计算机视觉、自然语言处理和音频处理三个领域的具体应用。同时,文中还介绍了AI在金融、医疗、教育、互联网及自动驾驶等行业中的广泛应用,强调了AI基础设施的重要性及其对企业竞争力的影响。通过阅读本文,读者不仅可以获得系统的AI知识,还能激发对AI系统研究的兴趣,掌握相关的设计原则与方法。
874 1
|
运维 Kubernetes 负载均衡
Kubernetes有哪些优势
【10月更文挑战第18天】Kubernetes有哪些优势
475 1
|
Linux
|
canal 消息中间件 缓存
面试题:如何解决缓存和数据库的一致性问题?
面试题:如何解决缓存和数据库的一致性问题?
522 1
|
Python
Collatz conjecture
【6月更文挑战第3天】
383 10