(对区间的模糊排序)考虑这样的一种排序问题:我们无法准确知道待排序的数字是什么。但对于每一个数,我们知道它属于实数轴上的某个区间。也就是说,我们得到了nnn个形如[ai,bi][a_i, b_i][ai,bi]的闭区间,其中ai≤bia_i ≤ b_iai≤bi。我们的目标是实现这些区间的模糊排序,即对j=1,2,…,nj = 1, 2, …, nj=1,2,…,n,生成一个区间的排列<i1,i2,…,in><i_1, i_2, …, i_n><i1,i2,…,in>,且存在cj∈[aij,bij]c_j∈[a_{i_j},b_{i_j}]cj∈[aij,bij],满足c1≤c2≤…≤cnc_1 ≤ c_2 ≤ … ≤ c_nc1≤c2≤…≤cn。
a. 为nnn个区间的模糊排序设计一个随机算法。你的算法应该具有算法的一般结构,它可以对左边端点(即aia_iai的值)进行快速排序,同时它也能利用区间的重叠性质来改善时间性能。(当区间重叠越来越多的时候,区间的模糊排序问题会变得越来越容易。你的算法应能充分利用这一重叠性持。)
b. 证明:在一般情况下,你的算法的期望运行时间为Θ(nlgn)Θ(n{\rm lg}n)Θ(nlgn)。但是,当所有的区间都有重叠的时候,算法的期望运行时间为Θ(n)Θ(n)Θ(n)(也就是说,存在一个值xxx,对所有的iii,都有x∈[ai,bi]x ∈ [a_i, b_i]x∈[ai,bi]。)你的算法不必显式地检查这种情况,而是随着重叠情况的增加,算法的性能自然地提高。
解
a.
对区间的模糊排序,简单来说只需要在每个区间上任意取一点cic_ici,对cic_ici进行排序即可。实际上,“““任意取区间的一点”””变成“““取区间左侧端点”””也是可行的。故对区间的模糊排序,可以转变成对区间左侧端点的排序。
我们现在考虑区间重叠的情况。如果有多个区间重叠,那么在排好序的序列中,这些重叠的区间之间的顺序是可以任意的。对于排序来说,可以认为这些重叠的区间是“““相等”””的关系。例如,考虑222个区间[ai,bi][a_i, b_i][ai,bi]和[aj,bj][a_j, b_j][aj,bj],当ai≤bja_i ≤ b_jai≤bj并且aj≤bia_j ≤ b_iaj≤bi时,两个区间就是重叠的,此时可以认为[ai,bi]=[aj,bj][a_i, b_i] = [a_j, b_j][ai,bi]=[aj,bj],如下图所示。
然而,这种“““相等”””关系不具备传递性,即[ai,bi]=[aj,bj][a_i, b_i] = [a_j, b_j][ai,bi]=[aj,bj]并且[aj,bj]=[ak,bk][a_j, b_j] = [a_k, b_k][aj,bj]=[ak,bk]成立,并不代表[ai,bi]=[ak,bk][a_i, b_i] = [a_k, b_k][ai,bi]=[ak,bk]成立。如下图所示[ai,bi][a_i, b_i][ai,bi]与[aj,bj][a_j, b_j][aj,bj]重叠,[aj,bj][a_j, b_j][aj,bj]与[ak,bk][a_k, b_k][ak,bk]重叠,但是[ai,bi][a_i, b_i][ai,bi]与[ak,bk][a_k, b_k][ak,bk]并不重叠。
那么我们应当如何判断多于222个的区间互相之间是“““相等”””的。以333个区间为例,[ai,bi][a_i, b_i][ai,bi]、[aj,bj][a_j, b_j][aj,bj]和[ak,bk][a_k, b_k][ak,bk]。先判断[ai,bi][a_i, b_i][ai,bi]和[aj,bj][a_j, b_j][aj,bj]是否重叠,如果重叠,找出重叠的范围,以下图为例,重叠的范围是[aj,bi][a_j, b_i][aj,bi]。我们再比较重叠范围[aj,bi][a_j, b_i][aj,bi]与第333个区间[ak,bk][a_k, b_k][ak,bk],如果二者重叠,说明333个区间是完全重叠的,它们互相之间也是“““相等”””的。如果还有第444个区间,那我们就需要比较前333个区间的重叠范围与第444个区间。
综合以上分析,我们可以借用思考题7-2的针对相同元素的快速排序。在每次递归调用PARTITION时,先选定最后一个区间作为主元。在遍历其他区间时,如果遇到一个区间与主元有重叠,则判定二者“““相等”””,并且以二者的重叠区域作为新的主元;如果判定二者“““不相等”””,则按照区间左侧端点的大小关系将区间划分到对应的子数组。由以上步骤可知,在遍历过程中,主元区间是有可能变化的。
以下只给出区间模糊排序中PARTITION过程的伪代码。
b.
如思考题7-2的结论,该算法的期望运行时间为Θ(nlgn)Θ(n{\rm lg}n)Θ(nlgn)。
如果所有区间都重叠,这意味着所有区间都“““相等”””,这种情况下PARTITION过程只会递归调用一次,所以此时算法的运行时间为Θ(n)Θ(n)Θ(n)。
算法导论 — 思考题7-6 对区间的模糊排序
