构造一个随机发生器

http://m.blog.csdn.net/blog/u012605629/40406577

构造一个随机发生器

2014-10-23阅读83 评论0

2.已知一随机发生器,产生0的概率是p,产生1的概率是1-p,
现在要你构造一个发生器,
使得它构造0和1的概率均为 1/2;
构造一个发生器,使得它构造1、2、3 的概率均为 1/3; ...,
构造一个发生器,使得它构造 1、2、3、...n 的概率均为1/n,要求复杂度最低。

/*
2.已知一随机发生器,产生0的概率是p,产生1的概率是1-p,
现在要你构造一个发生器,
使得它构造0和1的概率均为 1/2;
构造一个发生器,使得它构造1、2、3 的概率均为 1/3; ...,
构造一个发生器,使得它构造 1、2、3、...n 的概率均为1/n,要求复杂度最低。

思路:
由于需要产生1/2,而用1位0,或1位1无法产生等概率,
因此,考虑将随机数扩展成2位:
00   p*p
01  p*(1-p)
10  (1-p)*p
11 (1-p)*(1-p)
有上述分析知道,01和10是等概率的,因此我们只需要产生01和10就行了。
于是可以,遇到00和11就丢弃,只记录01和10。可以令,01表示0,10表示1,则等概率1/2产生0和1了。

对于n=2,一次性生成两个数字,认为01表示0,10表示1,
其它情况放弃,它们的概率都是p*(1-p);

对于n=3,一次性生成三个数字,认为001表示0,010表示1,100表示2,
其它情况放弃,它们的概率都是p*p*(1-p);

对于n=4,一次性生成是个数字,认为0001表示0,0010表示1,0100表示2,1000表示3,
其它情况放弃,它们的概率都是p*p*p*(1-p);

5为例,此时我们取x=2,因为C(2x,x)=C(4,2)=6是比5大的最小的x,
此时我们就是一次性生成4位二进制,把1出现个数不是2的都丢弃,
这时候剩下六个:0011,0101,0110,1001,1010,1100,
取最小的5个,即丢弃1100,那么我们对于前5个分别编号1到5,
这时候他们的概率都是p*p*(1-p)*(1-p)相等了。
关键是找那个最小的x,使得C(2x,x)>=n这样能提升查找效率。

因为C(n,i)最大是在i接近n/2的地方取得,此时我有更大比率的序列用于生成,
换句话说被抛掉的更少了,这样做是为了避免大量生成了丢弃序列而使得生成速率减慢,
实际上我之所以将x取定是为了让我取得的序列生成的概率互相相等,
比如C(2x,x)的概率就是[p(1-p)]^x,
互等的样例空间内保证了对应的每个值取得的样例等概率。

*/
时间: 2024-11-04 19:49:18

构造一个随机发生器的相关文章

一个随机数发生器(一)

老黄.老银和老阳共事宇宙中心某互联网企业H,并且同在一个由校招新生组成的Team里.刚走出校园的他们,对自己去年在校招这场演技大比拼中的表现意犹未尽,因此常会拿一些没什么实际意义的技术问题大谈特谈. 这次是午饭后的扯皮时间,这几个人就吸着免费的明胶酸奶,从一些概率问题讨论到了随机数发生器上…… 黄:像去年(校招),面试官就很喜欢问这种题目:给定一个[0, M)的均匀分布随机整数发生器(以下简称RNG),设计一个[0, N)的整数的均匀分布RNG. 阳:我被问的时候不知道怎么做,问我的人就得意的告

已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10

1.int rand7()    2.{    3.  return rand()%7+1;    4.}    5.  6.int rand10()  7.{  8.    int x=0;  9.    do  10.    {  11.        x=(rand7()-1)*7+rand7();  12.    }  13.    while(x>40);  14.    return x%10+1;  15.} 分析:要保证rand10()在整数1-10的均匀分布,可以构造一个1-1

写一个随机洗牌函数——概率题

题目描述: 写一个随机洗牌函数.要求洗出的52!种组合都是等概率的. 也就是你洗出的一种组合的概率是1/(52!).假设已经给你一个完美的随机数发生器. 解题思路: 这是一道概率题 随机洗牌,目的是要做到随机性,要求每一张牌出现的概率要相等. 我们常用的普通扑克牌54张,要做到每张牌出现的概率是1/(54!), 抽第一张牌概率:1/54: 抽第二张牌概率:1/53: 抽第三张牌概率:1/52: -- 一直这样随机地拿下去直到拿完最后1张,我们就从52!种可能中取出了一种排列, 这个排列对应的概率

linux内核分析 第三周 构造一个简单的Linux系统MenuOS

一.计算机的三个法宝 存储程序计算机,函数调用堆栈,中断二.操作系统的两把剑:1.中断上下文的切换,保存现场和恢复现场2.进程上下文的切换. 三.linux内核源代码的分析: ·arch/目录保存支持多种CPU类型的源代码,重点是x86·init目录:含有main.c,内核启动相关的代码基本都在init目录下·ipc目录:进程间的通信·kernel目录:有Linux内核的核心代码.四.构造一个简单的Linux系统 使用实验楼的虚拟机打开shell 1.cd LinuxKernel/2.qemu

作业3:构造一个简单的Linux系统MenuOS 20135115臧文君

构造一个简单的Linux系统MenuOS 注:作者:臧文君,原创作品转载请注明出处,<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.Linux内核源代码介绍 1.根目录 arch/x86目录下的代码是我们重点关注的,arch中包括支持不同CPU的源代码. init目录下包含内核启动相关的代码,如main.c(start_kernel函数相当于普通C程序的main函数,是Linux内核初始化的起点). ipc

Linux内核设计第三周——构造一个简单的Linux系统

Linux内核设计第三周 ——构造一个简单的Linux系统 一.知识点总结 计算机三个法宝: 存储程序计算机 函数调用堆栈 中断 操作系统两把宝剑: 中断上下文的切换 进程上下文的切换 linux内核源代码分析 arch/目录保存支持多种CPU类型的源代码 其中的关键目录包括:Documentation.drivers.firewall.fs(文件系统).include init目录:含有main.c,内核启动相关的代码基本都在init目录下 start_kernal()函数为启动函数,初始化内

一个随机上翻的小效果

html <!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="Content-Type" content="text/html; charset=uft-8"> <meta name="keywords

20135327郭皓--Linux内核分析第三周 构造一个简单的Linux系统MenuOS

Linux内核分析第三周  构造一个简单的Linux系统MenuOS 前提回顾 1.计算机是如何工作的三个法宝 1.存储程序计算机 2.函数调用堆栈 3.中断 2.操作系统的两把宝剑 中断上下文的切换 进程上下文的切换 第一讲  Linux内核源代码介绍 arch目录包括了所有和体系结构相关的核心代码.它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是Intel CPU及与之相兼容体系结构的子目录.PC机一般都基于此目录. init目录包含核心的初始化代码(不是系统的引导代

《Linux内核分析》第三周笔记 构造一个简单的Linux系统MenuOS

构造一个简单的Linux系统MenuOS 一.linux内核源代码简介 三大法宝(存储程序计算机.函数调用堆栈.中断)和两把宝剑(中断上下文的切换:保存现场和恢复现场.进程上下文的切换) 1.在linux内核源码里面arch占有的代码量相当庞大.arch/x86目录下的代码是我们重点关注的. 2.内核启动相关的代码基本都在init目录下(main.c). start_kernel是初始化linux内核的起点. start_kernel相当于c程序中的main函数 3.linux内核的核心代码在k