先看一个普通题目:

问题描述:现在有一个叫做Rand5的函数,可以生成等概率的[0, 5)范围内的随机整数,要求利用此函数写一个Rand3函数(除此之外,不能再使用任何能产生随机数的函数或数据源),生成等概率的[0, 3)范围内的随机整数。

代码:

Code Snippet
  1. def Rand3():
  2.   x = -1
  3.   while not 0 <= x < 3:
  4.     x = Rand5()
  5.   return x

代码本身是很简单的,至于结果为什么正确,首先看一个公式:

由RandN()生成RandM()_第1张图片

函数返回值为0,1,2,看下返回0的概率:

image

其中这个+的第一项是第一次rand就是0的概率,第二项就是第二次rand结果为0的概率,依次类推

稍微复杂点,如果是由较小的生成较大呢?

比如由randn生成randm,n<m.

首先系统的说明下:

1.

由RandN()生成RandM()_第2张图片概率的公式,用于计算,其实就是上面的公式

2.

image产生的数字范围为image

需要说明的是,在这个范围内每个数的概率是相同的,都是image,至于为什么要这么算,其实想象下n=10,该公式前部分产生十位数,后部分产生个位数,[0,99]数字平均分布,概率相同。

3.

最后一个公式,可能对照着例子来看会更容易懂一些,我们不妨设image,randm()产生的数字概率应均为image

由RandN()生成RandM()_第3张图片,同时需要满足image

上式的意思即在max个可能的结果里,只保留max-x个最小的,因为可以整除m,所以从里面取到的数概率相同。

希望没把你说糊涂,看下从原文里抄过来的例子:

Code Snippet
  1. def Rand7():
  2.   x = -1
  3.   while not 0 <= x < 21:
  4.     x = Rand5() * 5 + Rand5()
  5.   return x % 7

对比着说下:

数据源为Rand5()*5+Rand5(),可以保证[0,24]内每个数字概率均为1/25,排除掉一些,同时保证剩下的里面取[0,6]时是同等机会的,就可以了。这里的x取得是21。

如果有不对的地方,还请指出

参考资料:

http://www.gocalf.com/blog/build-rank3-from-rand5.html