算法导论5.3-1
算法导论练习5.3-1
Marceau教授不同意引理5.5证明中使用的循环不变式。他对第一次迭代之前循环不变式是否为真提出质疑。他的理由是,我们可以很容易宣称一个空数组不包含0排列。因此,一个空的子数组包含一个0排列的概率应是0,从而第一次迭代之前循环不变式无效。请重写过程RANDOMIZE-IN-PLACE,使得相关循环不变式适用于第一次迭代之前的非空子数组,并为你的过程修改引理5.5的证明。
RANDOMIZE-IN-PLACE的修改
由于需要适应的是第一次迭代之前的非空子数组,那么只需要作如下修改
1.将数组A的第一个元素的随机交换单独列出
2. 循环从数组A的第二个元素开始直至最后
伪代码
RANDOMIZE-IN-PLACE(A)
1 n=A.length
2 swap A[1] with A[RANDOM(1,n)]
3 for i=2 to n
4 swap A[i] with A[RANDOM(i,n)]
引理5.5证明修改
引理5.5的证明所需修改的地方是:
1.在3~4行for循环的第i次迭代之前,对每个可能的(i-1)排列,子数组A[1…i-1]包含这个(i-1)排列的概率是(n-i+1)!/(n-1)!
2.初始化:考虑正好在第一次循环迭代前的情况,此时i=2。有循环不变式可知,对每个可能的1排列,子数组A[1]包含这个1排列的概率是 (n-i+1)!/(n-1)!=(n-2+1)!/(n-1)!=(n-1)!/(n-1)!=1。子数组A[1]是一个单元素数组,并且1排列也就是一个单元素排列,因此A[1]包含任意1排列的概率就是1。在第一次循环迭代之前循环不变式成立。
3.保持:与引理5.5的证明类似只需要把 (n-i+1)!/n!改为(n-i+1)!/(n-1)!
4.终止:i=n+1,子数组A[2…n]是一个给定(n-1)排列的概率为 (n-(n+1)+1)!/(n-1)!=1/(n-1)!
明显地,修改完之后,我们证明出了子数组A[2…n]是给定n-1排列的概率是1/(n-1)!,再由第二行可知A[1]是给定1排列的概率为1/n,由此将两部分相乘合并,可以推知A[1…n]是给定n排列的概率是
(1/n)*(1/(n-1)!)=1/n!
针对《算法导论》中5.3-1练习题,讨论了Marceau教授对引理5.5证明中循环不变式的质疑。通过修改RANDOMIZE-IN-PLACE过程,确保循环不变式在第一次迭代前对于非空子数组有效,并重新证明了引理5.5。
564

被折叠的 条评论
为什么被折叠?



