zoukankan      html  css  js  c++  java
  • 《Mathematical Analysis of Algorithms》中有关“选择第t大的数”的算法分析

    开头废话

    这个问题是Donald.E.Knuth在他发表的论文Mathematical Analysis of Algorithms中提到的,这里对他的算法分析过程给出了更详细的解释。

    问题描述:

    给定一个数组a[1,2,...,n],用尽量少的比较次数找出数组中第t大的数。(假定这n个数两两不同)。

    算法描述:

    对于这个问题,可以很容易想到对应的算法。一个 (O(nlog n)) 的排序算法总能解决问题(然鹅今天我们并不对数组进行完全的排序)。
    参照快速排序中的Partition操作,将元素a[i]放到某个位置(k),使得排在它前面的元素都比它大(但不一定按照从大到小的次序排列),后面的元素都比它小。再根据a[i]的位置(k)(t)的大小关系,缩小查找范围再对子问题求解。
    对于每一次Partition操作,会有这样的3种情况:
    (1).若(k=t),算法结束。
    (2).若(k>t),则对a[i]~a[k-1]递归地求解
    (3).若(k<t),则对a[k+1]~a[j]递归地求解

    时间复杂度分析

    在这个问题的求解过程中,产生子问题的规模不断缩小。其中影响子问题的变量有(n)(数组的长度)和(t)(待查找的t)。Knuth记(C_{n,t})为在(n)个元素的数组中选择第(t)大的数所需的平均比较次数,这里有一个前提,我们假设数组的排列是随机的,每一次Partition找到第1,第2,...,第n大的数概率均为(frac 1 n)

    于是我们可以得到这样的式子:

    [egin {aligned} C_{1,1}&=0\ C_{n,t}&=n-1+frac 1n (A_{n,t}+B_{n,t}+0) end {aligned} ]

    其中(A_{n,t})(B_{n,t})的定义如下:

    [egin {aligned} A_{n,t}&=C_{n-1,t-1}+C_{n-2,t-2}+cdots+C_{n-t+1,1}\ B_{n,t}&=C_{t,t}+C_{t+1,t}+cdots+C_{n-1,t} end {aligned} ]

    这里(A_{n,t})对应的是递归过程中所有(k<t)的情况。对于这些情况,我们从数组的第(k+1)项开始向后的部分进行求解,如果把这部分看作一个新的数组,那么原始数组中第(t)大的数,在新的数组中是第(t-k)大的,也就是说这部分子问题是查找长度为(n-k)的数组中第(t-k)大的元素,其中(1leq k leq n.)

    类似的,(B_{n,t})对应所有(k>t)的情况,将数组第一项到第(k-1)项取出,看作一个新的数组,原始数组中第(t)大的数,在这新的数组中仍然是第(t)大,所以这部分的子问题是在长度为(k-1)的数组中选择第(t)大的数,其中(t+1leq k leq n.)

    括号内剩下的一项(0),对应的是(k=t)的情况,因为此时算法结束,不需要再求解子问题,所以比较次数为(0.)括号外的(n-1)是一次Partition要进行的比较次数。

    这样,括号内就等于所有可能规模子问题的比较次数的总和,将它乘以(frac 1n),就得到子问题比较次数的数学期望,即我们所求的平均情况下的预期比较次数。

    通过观察我们可以得到以下的递推公式:

    [egin {aligned} A_{n+1,t+1}&=C_{n-1,t-1}+C_{n-2,t-2}+cdots+C_{n-t+1,1}+C_{n,t}=A_{n,t}+C_{n,t}\ B_{n+1,t}&=C_{t,t}+C_{t+1,t}+cdots+C_{n-1,t}+C_{n+1-1,t}=B_{n,t}+C_{n,t} end{aligned} ]

    由上述等式作差消法,可以得到:

    [(n+1)C_{n+1,t+1}-nC_{n,t+1}-nC_{n,t}+(n-1)C_{n-1,t}\ =(n+1)n-n(n-1)-n(n-1)+(n-1)(n-2)\+(A_{n+1,t+1}-A_{n,t})-(A_{n,t+1}-A_{n-1,t})+(B_{n+1,t+1}-B_{n,t+1})-(B_{n,t}-B_{n-1,t}) \ =2+C_{n,t}-C_{n-1,t}+C_{n,t+1}-C_{n-1,t} ]

    合并同类项即可得到:

    [(n+1)C_{n+1,t+1}-(n+1)C_{n,t+1}-(n+1)C_{n,t}+(n+1)C_{n-1,t}=2\Downarrow\ C_{n+1,t+1}-C_{n,t+1}-C_{n,t}+C_{n-1,t}=frac{2}{n+1} ]

    接下来我们考察边界条件,当(t=1)时,由以上的式子我们可以得到下述方程组:

    [left{ egin{array}{l} C_{n,1}= n-1+frac{1}{n}(C_{1,1}+C_{2,1}+cdots +C_{n-1,1})\ B_{n,1}=C_{1,1}+C_{2,1}+cdots+C_{n-1,1}\ B_{n+1,1}=B_{n,1}+C_{n,1}\ C_{n,1}=n-1+frac{1}{n}(B_{n,1})\ C_{n+1,1}=n+frac{1}{n+1}(B_{n+1,1}) end{array} ight. ]

    消去方程组中包含(B)的项,可以得到:

    [egin{aligned} (n+1)C_{n+1,1}-nC_{n,1} &= (n+1)n-n(n-1)+C_{n,1}\ C_{n+1,1}-C_{n,1}&=2-frac{2}{n+1} quadquad(*) end{aligned} ]

    接下来求解(C_{n,1}):
    列出方程组:

    [left{ egin{array}{c} egin{aligned} C_{1,1}&=0\ C_{2,1}-C_{1,1}&=2-frac22\ C_{3,1}-C_{2,1}&=2-frac23\ cdots\ C_{n,1}-C_{n-1,1}&=2-frac2n\ end{aligned} end{array} ight.\ ]

    将以上(n)个方程求和,最终左边只剩下(C_{n,1}),得到如下式子:

    [egin{aligned} C_{n,1}&=2(n-1)-2sum_{k=2}^n frac1k\ quadDownarrow \ C_{n,1}&=2n-2sum_{k=1}^nfrac1k=2n-2H_n end{aligned} ]

    这里的(H_n)表示调和级数的前(n)项部分和。
    由于问题具有的对称性(这部分可自行证明),(C_{n,n}=C_{n,1}=2n-2H_n),将此式记作((Delta))
    ((*))式,可以列出以下方程组:

    [left{ egin{array}{l} (C_{n+1,t+1}-C_{n,t})-(C_{n,t+1}-C_{n-1,t})=frac2{n+1}\ (C_{n,t+1}-C_{n-1,t})-(C_{n-1,t+1}-C_{n-2,t})=frac2{n}\ quadquadquadquadquadquadquadquadcdots\ (C_{t+2,t+1}-C_{t+1,t})-(C_{t+1,t+1}-C_{t,t})=frac2{t+2}\ end{array} ight.\ ]

    再次对这(n-t)个方程累加,并联立((Delta))式,可以得到:

    [egin{aligned} C_{n+1,t+1}-C_{n,t}&=frac{2}{n+1}+frac{2}{n}+cdots+frac{2}{t+2}+C_{t+1,t+1}-C_{t,t}\ &=2(H_{n+1}-H_{t+1})+2-frac{2}{t+1} end{aligned} ]

    依次写出(C_{n,t}-C_{n-1,t-1})(C_{2,2}-C_{1,1})(n-1)个方程并再次累加(过程略去),可以推出:

    [C_{n,t}=2sum_{2leq kleq t}(H_{n-t+k}-H_{k}+1-frac1k)+C_{n+1-t,1} ]

    化简后:

    [C_{n,t}=2((n+1)H_n-(n+3-t)H_{n+1-t}-(t+2)H_t+n+3),quad(1leq tleq n) ]

    由于(t)(n)同阶,且平均情况下(t)的数学期望(E(t)=frac 2n),又 (H_n=Theta(log n)) ,所以:

    [C_{n,t}=O(nlog n) ]

    至此,时间复杂度的证明结束。

  • 相关阅读:
    复(学)习化学时突然的一个 idea
    [BZOJ3032]七夕祭
    [BZOJ3781]小B的询问
    [BZOJ4103][Thu Summer Camp 2015]异或运算
    [BZOJ4817][Sdoi2017]树点涂色
    [BZOJ2506]calc
    [BZOJ1283]序列
    win 解除鼠标右键关联
    linux 常用shell命令之wc
    shell cat 合并文件,合并数据库sql文件
  • 原文地址:https://www.cnblogs.com/allegro-vivace/p/12520377.html
Copyright © 2011-2022 走看看