这个问题有两个思路。
首先我们可以知道random(a,b)改写为random(0,b-a+1)+a-1
所以我们只需要知道怎么解决random(0,b-a+1)即可
第一种解法。
计算2的m次方+1大于等于b-a+1的最小的m,如b-a+1是6,m为3
用random(0,1)生成m次,形成一个二进制数。如果这个二进制数属于
0到b-a+1则选中,否则,从新运行第二步。
假设进行一系列伯努利试验,每次成功的概率是p,失败的概率是q=1-p,在取得一次成功前一共要进行多少次试验?令随机变量X为取得一次成功所要进行的试验次数,则X的取值范围{1,2,......}。对k>=1,因为在一次成功前有k-1次失败,从而有
Pr[X=k]= q^(k-1)p
满足上式的分布称为几何分布 [见算法导论 P686]
在算法中 p=(b-a+1)/2^m
期望运行次数(算法中生成m位序列的调用次数)为: E[X]=sum(k*q^(k-1)p) [k=1......+无穷]=1/p=2^m/(b-a+1)
用T表示调用一次RANDOM(0,1)所需要的时间,每次运行时间为输出m位bit的时间:O(log(b-a) × T)
期望运行时间:O(T × log(b-a) × 2^m/(b-a+1) )=(约等于)O(T × log(b-a)) (因为m=(约等于)log(b-a+1))
第二种解法
Ai ->事件第i个数最终被选中
Bim ->事件第i个数和其他m-1个数在这一轮筛选中被保留
Cim ->事件第i个数在这m个保留下来的子集中最终被选中
Pr{Ai/Bim} = Random(m) = 1/m;
Pr{Ai,Bim} = Pr{Bim}*1/m;
Pr{Ai} = ∑m=1~k-1Pr{Ai,Bim} = Pr{Ai} = ∑Pr{Bim}*1/m;
Pr{Bim} = C(k-1,m-1)(1/(2n-2)), 由于我们忽略了s为全1全0两种序列,所以其他序列的概率是1/(2n-2)
求解后可得 Pr{Ai} = 1/k。由于Random(2)是现成的,于是通过数学归纳法可知Random(k)通过上述算法都可以求解。
算法Random(k)的期望运行时间:只要不是出现s为全0全1这两种状况,算法规模就可以缩小。这两种状况的概率为 2/2k。依据伯努利试验的结论期望进行 Sk = 1/(1-2/2k)轮筛选就可以缩小问题规模。
T(k) = 筛选轮次*k*T(2) + T(i) ; i 以一定的概率分布于:1~k-1。
设常量 C = T(2)
E[T(k)] =Sk*k*C + E[T(1)]*C(k,1)(1/(2k-2)) +...+E[T(k-1)]*c(k,k-1)(1/(2k次-2))
这个递推式解不了。简化算法
上面的算法给出了比较严格的推理过程,但算法过程可以简化:如果k为偶数,则将S均分成两组,通过一次R(0,1)来淘汰其中一组;如果S为奇数,则用上述方法来分组,将占多数的一组淘汰。可以证明这个算法后也是正确的。只要在某一轮的测试中R(0,1)的输出为全0或全1,问题的规模就可以缩小一半。这样算法的期望运行时间递推式可以表示为 E[T(k)] <= Sk*k*C + E[T(k/2)], 应该为Θ(k)。