一、引入
(1)在5.2中,我们说:如果应聘者以随机顺序出现,那么聘用一个新的办公助理期望次数大约是ln n,注意,这里我们是通过改变我们的输入来确定聘用次数,从而确定成本的,而且其中一个输入对应一个成本。举个例子:假设排名列表A1=<1,2,3,4,5,6,7,8,9,10>会聘用10次,那么A2=<10,9,8,7,6,5,4,3,2,1>会聘用1次,A3=<5,2,1,8,4,7,10,9,3,6>会聘用3次,分别在5,8,10处聘用。
(2)这次我们要将随机性产生在算法上而不是输入上,比如输入A3也可以产生A1或者是A2的效果,不存在特定的输入能产生最好或者是最坏的情况。
(3)我们对之前的代码进行一点微调,变化主要是加入了第1行。
RANDOMIZED-HIRE-ASSISTANT(n)
1 randomly permute the list of candidates //随机排列候选者名单
//candidate 0 is a least-qualified dummy candidate(第一个雇佣者编号为0,比其他雇佣者更差)
2 best = 0
3 for i = 1 to n
4 interview candidate i
5 if candidate i is better than candidate best
6 best = i
7 hire candidate i
引理5.3:
内容:过程RANDOMIZED-HIRE-ASSISTANT的雇用费用期望是
解释:我们将输入数组进行随机变换以后,和之前通过改变输入来达成随机化的效果是一样的。
二、随机排列数组
目的是将给定的输入变换排列从而使输入随机化。
方法一:赋优先级法
1、基本操作:
将数组的每个元素A[i]赋一个随机的优先级P[i],然后依据优先级对数组A中的元素进行排序。
2、举例:
如果初始数组是A=<1,2,3,4>,随机选择的优先级是P=<36,3,62,19>,那么最终产生一个数组B=<2,4,1,3>,因为优先级数值越小的数字排在越前面。我们称这个过程为PERMUTE-BY-SORTING:
PERMUTE-BY-SORTING(A)
1 n = A.length
2 let P[1...n] be a new array //让P[1...n]成为一个数组
3 for i = 1 to n
4 P[i] = RANDOM(1, n³) //这里选择1到n³的随机数
5 sort A,using P as sort keys //依据优先级P给A排序
3、引理5.4
内容:假设所有优先级都不同,则过程PERMUTE-BY-SORTING产生输入的均匀随机排列(即该过程等可能地产生数字1~n³的一种排列)。
证明:较为麻烦,略。
方法二、原址排列给定数组
1、基本操作:
在进行第n次迭代时,元素A[i]是从元素A[i]和A[n]中随机选取的。第i次迭代之后,A[i]就不再改变。
2、举个例子:
A[1]是与A[1]到A[n]之中其中一个元素进行交换,然后A[1]就已经确定下来了;接着是A[2]和A[2]到A[n]之间的一个元素进行交换,然后确定下来,之后就是A[3]......直到A[n]。我们称这个过程为RANDOMIZE-IN-PLACE(A):
RANDOMIZE-IN-PLACE(A)
1 n = A.length
2 for i = 1 to n
3 swap A[i] with A[RANDOM(i,n)] //将A[i]和A[i]到A[n]中其中一个元素进行交换
3、引理5.5
内容:过程RANDOMIZE-IN-PLACE可计算出一个均匀随机排列。
证明:利用的是循环不变式,较为复杂,这里先不证明了。