随机排列算法及《算法导论》5.3节习题解答

随机排列算法及《算法导论》5.3节习题解答

  《算法导论》介绍了两种随机排列数组的算法。

  第一种算法是为数组的每个元素A[i]赋一个随机的优先级P[i],然后依据优先级对数组A中的元素进行排序。例如,如果初始数组A=(1,2,3,4),随机选择的优先级P=(36,3,62,19),则将产生一个数组B=(2,4,1,3),因为第2个优先级最小,接下来是第4个,然后第1个,最后第3个。我们称这个过程为PERMUTE-BY-SORTING:


1
2
3
4
5
6

PERMUTE-BY-SORTING(A)
n = A.length
let P[1..n] be a new array
for i = 1 to n
P[i] = RANDOM(1,n^3)
sort A, using P as sort keys

第5行选取一个在1~n3之间的随机数。我们使用范围1~n3是为了让P中所有优先级尽可能唯一。我们假设所有的优先级都唯一。

  第二种算法是原址排列给定数组。过程RANDOMIZE-IN-PLACE在O(n)时间内完成。在进行第i次迭代时,元素A[i]是从元素A[i]到A[n]中随机选取的。第i次迭代以后,A[i]不再改变。


1
2
3
4

RANDOMIZE-IN-PLACE(A)
n = A.length
for i = 1 to n
swap A[i] with A[RANDOM(i,n)]

  以上两种算法都能计算出数组A的一个均匀随机排列,明显第二种算法更加漂亮。

  练习5.3有几个RANDOMIZE-IN-PLACE算法的变形,但他们计算出的排列都不是A的均匀随机排列,下面一起来看一下。


5.3-2 Kelp教授决定写一个过程来随机产生除恒等排列(identity permutation)外的任意排列。他提出了如下过程:


1
2
3
4

PERMUTE-WITHOUT-IDENTITY(A)
n = A.length
for i = 1 to n-1
swap A[i] with A[RANDOM(i+1,n)]

这段代码实现了Kelp教授的意图吗?

  没有。虽然这个过程不能产生恒等排列,但也不能产生除恒等排列完的任意排列。

  除恒等排列外的任意排列共有n!-1个,但是此过程只能产生(n-1)(n-2)…1=(n-1)!个,还有(n!-1)-(n-1)!个排列不能产生。举个例子:A=(a1,a2,…,an),a1必须和a2,a3,…,an中的某一个交换,假设和aj交换,则a1永远不可能回到第一个位置了,因为当循环到位置j时,aj(原来的a1)也只能被交换到a(j+1),…,an中。而除恒等排列外的任意排列明显包含a1在第一个位置上的排列。

  所以过程PERMUTE-WITHOUT-IDENTITY不能产生除恒等排列外的任意排列。


5.3-3 假设我们不是将元素A[i]与子数组A[i..n]中的一个随机元素交换,而是将它与数组任何位置上的随机元素交换:


1
2
3
4

PERMUTE-WITH-ALL(A)
n = A.length
for i = 1 to n
swap A[i] with A[RANDOM(1,n)]

这段代码会产生一个均匀随机排列吗?为什么会或为什么不会?

  这段代码不会产生一个均匀随机的排列,使用反证法如下。

  假设这段代码会产生一个均匀随机的排列,且假设n=3,则三个元素的均匀随机排列共有3!=6个,且每个排列出现的概率为1/6。但是过程PERMUTE-WITH-ALL一共产生n3=27(n=3,3次for循环,每次RANDOM(1,3)有3可能)个排列,假设共有m个互异的排列,且排列是均匀随机的,则每个互异的排列的概率为m/27,且满足m/27=1/6。但是m没有整数解,所以原假设不成立,即过程PERMUTE-WITH-ALL不能产生一个均匀随机的排列。

  实际上当n=3时,产生的排列及概率如下:

(1,2,3)4/27(1,3,2)5/27(2,1,3)5/27(2,3,1)5/27(3,1,2)4/27(3,2,1)4/27

虽然他们产生了所有的排列,且概率总和为1,但是他们不是随机均匀的,因为每一种排列的概率不相等。


5.3-4 Armstrong教授建议用下面的过程来产生一个均匀随机排列:


1
2
3
4
5
6
7
8
9
10

PERMUTE-BY-CYCLIC(A)
n = A.length
let B[1..n] be a new array
offset = RANDOM(1,n)
for i = 1 to n
dest = i + offset
if dest > n
dest = dest - n
B[dest] = A[i]
return B

请说明每个元素A[i]出现在B中任何特定位置的概率是1/n。然后通过说明排列结果不是均匀随机排列,表明Armstrong教授错了。

  A[i]出现在B中的位置是由offset决定的,而且只要offset决定了,则整个B就决定了;又因为offset=RANDOM(1,n),所以特定的offset出现的概率相等,都为1/n,所以每个元素A[i]出现在B中任何特定位置的概率是1/n。

  因为offset只有n种可能,所以B也只有n种可能,但是A的所有均匀随机排列共有n!种情况,所以还有n!-n种情况没有出现,即排列结果不是均匀随机的。


*5.3-5 证明:在过程PERMUTE-BY-SORTING的数组P中,所有元素都唯一的概率至少是1-1/n。

  假设RANDOM(1,n3)产生的n个数为a1,a2,…,an,事件Xi表示a1~ai互不相等,则Xn表示a1~an互不相等,Xn是在X(n-1)的基础上保证an和a1~a(n-1)互不相等,即Xn={an不等于a1,a2,…,a(n-1)之一}∩X(n-1),于是P(Xn)=P{{an不等于a1,a2,…,a(n-1)之一}∩X(n-1)},根据条件概率公式得:

随机排列算法及《算法导论》5.3节习题解答

所以数组P中,所有元素都唯一的概率至少是1-1/n。

 

 


5.3-6 请解释如何实现算法PERMUTE-BY-SORTING,以处理两个或更多优先级相同的情形。也就是说,即使有两个或更多优先级相同,你的算法也应该产生一个均匀随机排列

  对几个优先级相同的项,再进行一轮随机优先级排序;如果再有相同,再进行一次…思路就是要确保这几个优先级相同的项得到随机的排列。

转自http://beeder.github.io/2014/12/19/random-permutation-algorithms-and-some-solutions-to-clrs-ch5-3/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章