算法導論中文第三版Chapter 9
一些概念
- 順序統計量:在n元素集合中,第i個順序統計量是該集合中第i小的元素。
- 中位數:所屬集合的中點元素。如果集合元素數為奇數,那么它的中位數是唯一的;如果集合元素數為偶數,那么它的中位數有兩個,較?。ɑ蜉^前)的數稱為下中位數,較大(或較后)的數稱為上中位數。
- 最大值:第一個順序統計量。
- 最小值:最后一個順序統計量。
順序統計量選擇問題
- 輸入:一個包含n個(互異)數的集合A和一個整數i,1≤i≤n。
- 輸出:元素x∈A,且A中恰好有i-1個元素小于x。
的
在一個由n個元素組成的集合中,第i個順序統計量(order statistic)是該集合中第i小的元素。例如,在一個元素集合中,最小值是第1個順序統計量(i=1),最大值是第n個順序統計量(i=n)。用非形式化的描述來說,一個中位數(median)是它所屬集合的“中點元素”。當n為奇數時,中位數是唯一的,位于i=(n+1)/2處。當n為偶數時,存在兩個中位數,分別位于i=n/2和i=n/2+1處。因此,如果不考慮n的奇偶性,中位數總是出現在i=floor((n+1)/2)處(下中位數)和i=ceil((n+2)/2)處(上中位數)。為了簡便起見,本書中所用的“中位數”都是指下中位數。本章將討論從一個由n個互異的元素構成的集合中選擇第i個順序統計量的問題。為了方便起見,假設集合中的元素都是互異的,但實際上我們所做的都可以推廣到集合中包含重復元素的情形。我們將這一問題形式化定義為如下的選擇問題:輸入:一個包含n個(互異的)數的集合A和一個整數i, 1<=i<=n。輸出:元素x屬于A,且A中恰好有i-1個其他元素小于它。我們可以在O(nlgn)時間內解決這個問題,因為我們可以用堆排序或歸并排序對輸入數據進行排序,然后在輸出數組中根據下標找出第i個元素即可。本章將介紹一些更快的算法。在9.1節中,我們將討論從一個集合中選擇最小元素和最大元素的問題。對于一般化選擇問題的更有意思的討論將在接下來的兩節中進行。9.2節將分析一個實用的隨機算法,它在元素互異的假設條件下可以達到O(n)的期望運行時間。9.3節將給出一個更具有理論意義的算法,它在最壞情況下的運行時間為O(n)。
9.1 最小值和最大值在一個有n個元素的集合中,需要做多少次比較才能確定其最小元素呢?我們可以很容易地給出n-1次比較這個上界:依次遍歷集合中的每個元素,并記錄下當前最小元素。在下面的程序中,我們假設該集合元素存放在數組A中,且A.length=n:
當然,最大值也可以通過n-1次比較找出來。這是我們能得到的最好結果嗎?是的,對于確定最小值問題,我們可以得到其下界就是n-1次比較。對于任意一個確定最小值的算法,可以把它看成是各元素之間進行的一場錦標賽。每次比較都是錦標賽中的一場比賽,兩個元素中較小的獲勝。需要注意的是,除了最終獲勝者以外,每個元素都至少要輸掉一場比賽。因此,我們得到結論:為了確定最小值,必須要做n-1次比較。因此,從所執行的比較次數來看,算法MINIMUM是最優的。同時找到最小值和最大值在某些應用中,我們必須要找出一個包含n個元素的集合中的最小值和最大值。例如,一個圖形程序可能需要轉換一組(x, y)數組,使之能適合一個矩形顯示器或其他圖形輸出裝置。為了做到這一點,程序必須首先確定每個坐標中的最小值和最大值。就這一點來說,用漸近最優的THETA(n)次比較,在n個元素中同時找到最小值和最大值的方法是顯然的:只要分別獨立地找出最小值和最大值,這各需要n-1次比較,共需2n-2次比較。事實上,我們只需要最多3floor(n/2)次比較就可以同時找到最小值和最大值。具體的方法是記錄已知的最小值和最大值。但我們并不是將每一個輸入元素與當前的最小值和最大值進行比較——這樣做的代價是每個元素需要2次比較,而是對輸入元素成對地進行處理。首先,我們將一對元素相互進行比較,然后把較小的與當前最小值比較,把較大的與當前最大值進行比較。這樣,對每兩個元素共需3次比較。如何設定已知的最小值和最大值的初始值依賴于n是奇數還是偶數。如果n是奇數,我們就將最小值和最大值的初值都設為第一個元素的值,然后成對地處理余下的元素。如果n是偶數,就對前兩個元素做一次比較,以決定最小值和最大值的初值,然后與n是奇數的情形一樣,成對地處理余下的元素。下面來分析一下總的比較次數。如果n是奇數,那么總共進行3floor(n/2)次比較。如果n是偶數,則是先進行一次初始比較,然后進行3(n-2)/2次比較,共3n/2-2次比較。因此,不管是哪一種情況,總的比較次數至多是3floor(n/2)。練習9.1-1 證明:在最壞情況下,找到n個元素中第二小的元素需要n+ceil(lgn)-2次比較。(提示:可以同時找最小元素。)http://clrs.skanev.com/09/01/01.html* 9.1-2 證明:在最壞情況下,同時找到n個元素中最大值和最小值的比較次數的下界是ceil(3n/2)-2。(提示:考慮有多少個數有成為最大值或最小值的潛在可能,然后分析一下每一次比較會如何影響這些計數。)http://clrs.skanev.com/09/01/02.html
作者:Beryllium鏈接:http://www.lxweimin.com/p/148f4417b6bb來源:簡書著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
一般選擇問題看起來要比找最小值這樣的簡單問題更難。但令人驚奇的是,這兩個問題的漸近運行時間卻是相同的:THETA(n)。本節將介紹一種解決選擇問題的分治算法。RANDOMIZED-SELECT算法是以第7章的快速排序算法為模型的。與快速排序一樣,我們仍然將輸入數組進行遞歸劃分。但與快速排序不同的是,快速排序會遞歸處理劃分的兩邊,而RANDOMIZED-SELECT只處理劃分的一邊。這一差異會在性能分析中體現出來:快速排序的期望運行時間是THETA(nlgn),而RANDOMIZED-SELECT的期望運行時間為THETA(n)。這里,假設輸入數據都是互異的。RANDOMIZED-SELECT利用了7.3節介紹的RANDOMIZED-PARTITION過程。與RANDOMIZED-QUICKSORT一樣,因為它的部分行為是由隨機數生成器的輸出決定的,所以RANDOMIZED-SELECT也是一個隨機算法。以下是RANDOMIZED-SELECT的偽代碼,它返回數組A[p..r]中第i小的元素。
RANDOMIZED-SELECT的運行過程如下:第1行檢查遞歸的基本情況,即A[p..r]中只包括一個元素。在這種情況下,i必然等于1,在第2行,我們只需將A[p]返回作為第i小的元素即可。其他情況,就會調用第3行的RANDOMIZED-PARTITION,將數組A[p..r]劃分為兩個(可能為空的)子數組A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每個元素都小于或等于A[q],而A[q]小于A[q+1..r]中的每個元素。與快速排序中一樣,我們稱A[q]為主元(pivot)。RANDOMIZED-SELECT的第4行計算子數組A[p..q]內的元素個數k,即處于劃分的低區的元素的個數加1,這個1指主元。然后,第5行檢查A[q]是否是第i小的元素。如果是,第6行就返回A[q]。否則,算法就要確定第i小的元素落在兩個子數組A[p..q-1]和A[q+1..r]的哪一個之中。如果i<k,則要找的元素落在劃分的低區。第8行就在低區的子數組中進一步遞歸查找。如果i>k,則要找的元素落在劃分的高區中。因為我們已經知道了有k個值小于A[p..r]中第i小的元素,即A[p..q]內的元素,所以,我們所要找的元素必然是A[q+1..r]中的第i-k小的元素。它在第9行中被遞歸地查找。上述程序看起來允許遞歸調用含有0個元素的子數組,但練習9.2-1要求證明這種情況不可能發生。RANDOMIZED-SELECT的最壞情況運行時間為THETA(n^2),即使是找最小元素也是如此,因為在每次劃分時可能極不走運地總是按余下的元素中最大的來進行劃分,而劃分操作需要THETA(n)的時間。我們也將看到該算法有線性的期望運行時間,又因為它是隨機化的,所以不存在一個特定的會導致其最壞情況發生的數據。為了分析RANDOMIZED-SELECT的期望運行時間,我們設該算法在一個含有n個元素的輸入數組A[p..r]上的運行時間是一個隨機變量,記為T(n)。下面我們可以得到E[T(n)]的一個上界:程序RANDOMIZED-SELECT能等概率地返回任何元素作為主元。因此,對每一個k(1<=k<=n),子數組A[p..q]有k個元素(全部小于或等于主元)的概率是1/n。對所有k=1, 2, ..., n,定義指示器隨機變量Xk為:
然后,假設元素是互異的,我們有:
(9.1)
當調用RANDOMIZED-SELECT并選擇A[q]作為主元時,事先并不知道是否會立即得到正確答案而結束,或者在子數組A[p..q-1]上遞歸,或者在子數組A[q+1..r]上遞歸。這個決定依賴于第i小的元素相對于A[q]落在哪個位置。假設T(n)是單調遞增的,通過評估最大可能的輸入數據遞歸調用所需時間,我們可以給出遞歸調用所需時間的上界。也就是說,為了得到上界,我們假定第i個元素總是在劃分中包含較大元素的一邊。對一個給定的RANDOMIZED-SELECT,指示器隨機變量Xk恰好在給定的k值取1,對其他值都為0。當Xk=1時,我們可能要遞歸處理的兩個子數組的大小分別為k-1和n-k。因此可以得到遞歸式:
兩邊取期望值,得到
公式(C.24)的應用依賴于Xk和T(max(k-1, n-k))是獨立的隨機變量。練習9.2-2要求證明這個命題。下面來考慮一下表達式max(k-1, n-k)。我們有
如果n是偶數,則從T(ceil(n/2))到T(n-1)的每一項在總和中恰好出現兩次。如果n是奇數,除了T(floor(n/2))出現一次意外,其他這些項也都會出現兩次。因此,我們有
我們將用替代法來得到E[T(n)]=O(n)。假設對滿足這個遞歸式初始條件的某個常數c,有E[T(n)]<=cn。假設對小于某個常數的n,有T(n)=O(1)(稍后將用到這個常數)。同時,還要選擇一個常數a,使得對所有的n>0,上式中O(n)項所描述的函數(用來表示算法運行時間中的非遞歸部分)有上界an。利用這個歸納假設,可以得到:
為了完成證明,還需要證明:對足夠大的n,最后一個表達式至多是cn,等價地,cn/4-c/2-an>=0。如果在上式兩邊加上c/2,并且提取因子n,就可以得到n(c/4-a)>=c/2。只要我們選擇的常數c能夠滿足c/4-a>0,即c>4a,就可以將兩邊同除以c/4-a,得到
因此,如果假設對所有n<2c/(c-4a),都有T(n)=O(1),那么就有E[T(n)]=O(n)。我們可以得出這樣的結論:假設所有元素是互異的,在期望線性時間內,我們可以找到任一順序統計量,特別是中位數。練習9.2-1 證明:在RANDOMIZED-SELECT中,對長度為0的數組,不會進行遞歸調用。9.2-2 請討論:指示器隨機變量Xk和T(max(k-1, n-k))是獨立的。9.2-3 給出RANDOMIZED-SELECT的一個基于循環的版本。9.2-4 假設用RANDOMIZED-SELECT去選擇數組A=<3, 2, 9, 0, 7, 5, 4, 8, 6, 1>的最小元素,給出能夠導致RANDOMIZED-SELECT最壞情況發生的一個劃分序列。
作者:Beryllium鏈接:http://www.lxweimin.com/p/3ff11606328a來源:簡書著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。