1. 程式人生 > >隨機演算法之隨機選擇

隨機演算法之隨機選擇

1. 問題定義

        輸入:n個無序元素 S = {x1, x2, ... , xn};

        輸出:S中第k個最小元素。

2. 隨機演算法

        如果先對n個元素進行遞增排序,然後直接返回排在第k個位置上的元素即可求解。因此,此題的時間複雜度就是排序的時間複雜度O(nlogn)。隨機演算法給出一個新的思路,能夠以很高的概率確保線上性時間O(n)內求得問題的解。


        基本思路:為了能夠線上性時間求解,隨機演算法每次只是對部分元素進行排序,然後進一步求解。隨機演算法一般分為三個階段:第一個階段,從n個元素中選取n^(3/4)個元素進行排序(均勻、獨立、可放回地抽樣),記為R;第二個階段,試圖從R中選出兩個元素L和H使得L ≤ min(S,k) ≤ H, 利用概率的知識原先在S中的第k小元素求得在R中應該是k' = k/n * n^(3/4), 由於k'存在誤差,查詢的位置從k'左右擴充套件n^(1/2)個元素,因此l取max(k' - n^0.5, 0), h取min(k' + n^0.5, n^3/4

),最後L取R中第l個元素,H取R中第h個元素;第三個階段,從S中抽取所有介於L和H之間的元素構成子集P,如果min(S, k)∈P且|P| ≤ 4*n^3/4 + 1,則可以在O(n)時間內對P進行排序並找到目標元素,其中min(S, k)∈P當且僅當Lp≤ k ≤Hp(Lp為S中比L小的元素個數,Hp為S中比H小的元素個數)。演算法步驟如下:

         1. R = 獨立、均勻、可放回地從S中選取n^(3/4)個元素;

         2. 在O(n)時間內對R進行排序 ;

         3. k' = k/n * n^(3/4) ;

         4. l =max( k' - n^1/2, 0), h = min(k' + n^1/2, n^3/4);

         5. L = min(R, l), H = min(R, h)   // min(R,l)的意思是從R中選取第l個元素;

         6. Lp = Rank(S,L),  Hp = Rank(S,H)  // Rank(S,L) 的意思是S中比L小的元素個數;

         7. P = {y∈S| L≤ y ≤H };

         8. If  min(S, k)∈P and |P| ≤ 4*n^3/4 + 1  //  min(S, k)∈P 當且僅當 Lp≤ k ≤Hp;

         9. Then  對P中的元素進行排序,返回第k-Lp位置上的元素, 演算法結束;

        10. Else goto 1.

3. 演算法的效能分析

         演算法第1步的開銷為O(n^3/4)=O(n); 第2步的開銷為O(n); 第3~5步的開銷為1;第6步需要比較2n次; 第7步是O(n)時間;第8步只需O(1)的時間進行判斷;第9步需要O(n)時間。於是演算法第1~9步執行一遍總的時間開銷為O(n)。藉助切比雪夫不等式,可以證明該演算法在O(n)時間內求出min(S,k)的概率是1 - O(n^-1/4)。