说明
本文所说的均为伪代码,代码实现根据自己习惯语言编写.
什么是随机数
随机数是不同随机试验的结果。它在不同统计领域均有广泛地应用,比如从统计样本中抽取一定数量的个体。产生随机数有多种不同的方法,而这些方法被称为随机数生成器。随机数的性质是等概率,不可预测,例如最简单随机数整数生成器求模运算。 伪代码见如下
`生成(0,n)的随机数`
任意输入一个整数z
随机数R则等于 z % n 的求模
结果R则是所求的随机数
对应python中的randint(0,n)的函数
这种方法产生的数一定是0,n范围内,且每个数字出现的概率取决于z。因为我们无法判断输入的数z的取值范围,所以生成器生成的结果满足随机数的性质,等概率,不可预测。
构造属于特定的随机数生成器
构造属于特定的随机数生成器。首先要有基础的随机数生成器,也即是rand(),我们会根据这个基础生成器rand()构造出我们特定需要的随机数生成器,以下是几个随机生成器的应用:
应用一:构造随机数生成数
目前有一基础的随机函数rand6(), 它可以产生0-6的随机整数。要求产生1-10的随机数:
-
方法一
R = 0 R = rand6() //生成随机数 if R >= 5 : //若R大于>5 do { tmp_R = rand6() //重新生成随机数,直至tmp_R范围是0-4 if tmp_R < 5: R =6+ tmp_R //范围是6-10 break } while True else R = R+1 //范围是1-5 return R //范围1-10
-
方法二
根据奇偶性,因为任何的整数都能通过0,1表示, 而0000-1111可以表示为0-16的整数
。rand6()生成数的奇偶性不是等概率的,很明显奇数是1,3,5,偶数是0,2,4,6。在这里,我们剔除6,在进行下一步:bin_str = "" //step count = 0 do { R = rand6() if R > 5: continue bin_str += int2str(R % 2) //产生0或者1 count += 1 } while (count < 5) return binStr2int(bin_str)+1 //0,1字符串转成10进制整数 若返回值大于10, 则需要重新在来
`
应用二:水库抽样
应用范围,对于未知大小的样本,定量抽取k个个体。例如,随机抽取文档任何k行文本数据。详情可以参看维基百科,百度百科等解释:
条件
1.样本抽象是n个元素的数组
2.抽取个体数量为k个
3.随机数产生器
伪代码如下
for i in (1,2,...,n):
do
if i <= k :
tmp[i] = Arrary[i]
else: // i > k
M = rand(1, i) // 产生0, i-1 范围的随机数。参考应用一
if M < k :
tmp[M] = Arrary[i]
then
这个算法的好处是复杂度为O(n)+常数时间, 主要根据当前数据的大小而定。
原理是:
-
当前k个元素进来,不需考虑,因为i始终小于k;
-
当i>=k时,此时元素面临两种情况,进来并替换前k个元素中的其中一个;不进来。我们分析以下两种情况的概率,说明它符合随机生成器的性质等概率,不可预测;
- 第i个元素不进来(i=k+1), 其概率
P(fail)=1-P(能被替换)
,P(能被替换)=前面k个元素/i=k/(k+1)
,P(fail)=1/(k+1)
- 第i个元素进来(i>=k), 其概率
P(succ)=P(能被替换)*P(第几个元素被替换)
,P(能被替换)=k/(k+1)
,P(第几个元素被替换)=1/k
,P(succ)=1/(k+1)
- 第i个元素不进来(i=k+1), 其概率