双调排序
主要參考?http://www.cs.rutgers.edu/~venugopa/parallel_summer2012/bitonic_overview.html
雙調(diào)排序的時間復雜度是?O(n (logn)^2),這是說的串行的時間復雜度。這個算法的好處是可以很容易的實現(xiàn)并行,用多個核的并行運算提速,會比串行排序(快排等)要加速很多。
首先要清楚什么是雙調(diào)序列。是指一個序列前段是升序或者降序,后段是降序或者升序。那么對于任意兩個數(shù),都是雙調(diào)序列。
基本的雙調(diào)排序只能處理2^n個數(shù)的序列。
首先我們定義一個操作是sortSeq, 輸出是一個雙調(diào)序列,其中前半段s1是升序,后半段s2是降序,設這個序列的長度是n,那么s1的元素是<a0,a1,..,an/2-1>,s2的元素是<an/2,an/2+1,..,an>
對s1和s2按照元素的對應位置進行如下操作:
如果a0 <= an/2, 那么不進行操作,否則交換兩個元素
用形式化的表示就是:
交換之后,s1中的序列就是兩兩比較較小的值,s2的序列就是兩兩比較較大的值
本來s1是升序,s2是降序的,經(jīng)過如此操作之后,s1也是雙調(diào)的,s2也是雙調(diào)的
大家可以看出在構(gòu)建s1和s2時,可以用n/2個線程對兩兩元素進行比較交換,從而實現(xiàn)并行運算
再對s1進行sortSeq操作,對s2進行sortSeq操作
就這樣遞歸操作,知道傳入sortSeq的序列長度為2
最終s就是升序排列的
那么如何構(gòu)建最初的雙調(diào)序列?
算法采用從低向上的方法逐步構(gòu)建雙調(diào)序列
對于無序數(shù)組,A,相鄰的兩個數(shù)肯定是雙調(diào)序列,比如(a0,a1), (a2,a3)等等
首先對a0,a1傳入sortSeq,變成升序序列,a2,a3傳入sortSeq,變成降序序列,a4,a5變成升序序列.....
接下來步長變?yōu)?,a0,a1,a2,a3是雙調(diào)序列,傳入sortSeq變成升序序列,a4,a5,a6,a7也是雙調(diào)的,傳入sortSeq變成降序序列
.....
最后步長是n,前n/2元素是升序,后n/2是降序,傳入sortSeq變成升序序列
至此算法完成
算法如上圖所示,左邊是無序的輸入序列,右邊是輸出序列,中間的是排序網(wǎng)絡,兩個圈連接的是比較器,
圖上所示還差最后一步的sortSeq,將其變成升序序列
如果元素個數(shù)不滿足2^n次方呢?
http://blog.csdn.net/ljiabin/article/details/8630627
排序網(wǎng)絡
n!=2^k的雙調(diào)排序網(wǎng)絡
經(jīng)典的雙調(diào)排序網(wǎng)絡的設計是用來解決輸入長度n=2^k的情況。下面提出了一種對于任意n的雙調(diào)排序網(wǎng)絡算法,它的正確性來自于0-1原理。
問題:
對于長度為n=2^k的雙調(diào)排序網(wǎng)絡包含如表1所示的三塊。左邊兩塊是雙調(diào)排序網(wǎng)絡,把原序列均分為兩半,分別按升序和降序排列;右邊一塊是雙調(diào)合并網(wǎng)絡,歸并兩半有序序列,得到整個有序序列。
圖1:雙調(diào)排序(2^k)的結(jié)構(gòu)
基礎定義:
定義:a = a0,…,a(n-1)是一個0-1序列。
??? 當序列只包含0時,我們稱a為清潔的0序列,即a0,…,a(n-1) = 0.
??? 當序列只包含1時,我們稱a為清潔的1序列,即a0,…,a(n-1) = 1.
??? 如果a序列是由一個清潔的0序列后接一個清潔的1序列構(gòu)成的,那么我們稱a單調(diào)遞增,即a0,…,a(k-1) = 0, ak,…,a(n-1) = 1.
??? 如果a序列是由一個清潔的1序列后接一個清潔的0序列構(gòu)成的,那么我們稱a單調(diào)遞減,即a0,…,a(k-1) = 1, ak,…,a(n-1) = 0.
如果a序列依次由一個清潔的0序列、一個清潔的1序列和一個清潔的0序列構(gòu)成,那么我們稱a序列雙調(diào)遞增,即a0,…,a(k-1)= 0, ak,…,a(m-1) = 1, am,…,a(n-1) = 0.
如果a序列依次由一個清潔的1序列、一個清潔的0序列和一個清潔的1序列構(gòu)成,那么我們稱a序列雙調(diào)遞減,即a0,…,a(k-1)= 1, ak,…,a(m-1) = 0, am,…,a(n-1) = 1.
根據(jù)這個定義,一個清潔的序列既可以被稱作單調(diào)遞增,也可以被稱作單調(diào)遞減。相似的,一個單調(diào)序列既可以被稱作雙調(diào)遞增,也可以被稱作雙調(diào)遞減。圖2展示了雙調(diào)序列的一些例子,其中,白色部分代表0,灰色部分代表1,箭頭代表特殊情況關(guān)系(如清潔的0序列是雙調(diào)遞增序列的一種特殊情況)。
圖2:雙調(diào)序列的例子
定理:設定a是一個0-1序列,如果a是一個清潔的0/1序列或單調(diào)遞增/減序列或雙調(diào)遞增/減序列,那么a的子序列a’也是。
想法:
標準的雙調(diào)排序使用了比較網(wǎng)絡Bp(p=2^k),我們根據(jù)比較網(wǎng)絡Bp推導出對于任意n的網(wǎng)絡Bn,p是大于的第一個2的冪次方,然后僅僅對n-p/2的元素使用比較網(wǎng)絡。圖3展示了n=6時的比較網(wǎng)絡Bn,把它嵌入到p=8的比較網(wǎng)絡Bp,僅僅使用了前兩個比較器。
圖3:比較網(wǎng)絡Bp應用于長度為n的雙調(diào)遞減0-1序列a
定理:n!=2^k,p是大于n的最小的2的冪次方,對雙調(diào)遞減0-1序列a應用比較網(wǎng)絡Bn,產(chǎn)生序列b和c具有以下特性(圖3中):
|b| = p/2, b =2^k,
對任意I,j有bi <= cj,
b是雙調(diào)序列,c是雙調(diào)遞減序列。
證明:如果輸入的長度為n的雙調(diào)遞減a被用1填充為長度為p的序列a’,那么這個序列仍保持雙調(diào)遞減。應用比較網(wǎng)絡Bp將產(chǎn)生兩個雙調(diào)序列b和c’,|b| = p/2,對于任意i和j,bi <= cj(見標準雙調(diào)排序)。由于填充的1保持在末尾不變,所以c’雙調(diào)遞減。如果不考慮后面填充的1,序列c’的子序列c也是雙調(diào)遞減。后面屬于Bp卻不屬于Bn的比較是多余的,因此網(wǎng)路Bn應用于序列a會得到同樣的結(jié)果。
根據(jù)這個定理,應用于雙調(diào)序列b的比較網(wǎng)絡Bp(p=2^n)和應用于雙調(diào)遞減序列c的網(wǎng)絡Bn(n任意)的遞歸程序?qū)a(chǎn)生一個有序序列。
如果排序的方向是遞減而非遞增,這個定理同樣適用于“雙調(diào)遞增”而非“雙調(diào)遞減”。證明時,原序列a用0而非1來填充。
最開始,一個序列通過對前一半遞減排序?qū)笠话脒f增排序得到一個雙調(diào)遞減序列。圖4展示了對任意輸入長度n的雙調(diào)排序網(wǎng)絡的結(jié)構(gòu)圖,由于這個網(wǎng)絡對每一個0-1序列排序,根據(jù)0-1原理它對任意長度的0-1序列排序。
圖4:對任意輸入長度n的雙調(diào)排序結(jié)構(gòu)圖
程序:
下面的程序?qū)崿F(xiàn)了對于任意輸入長度n的雙調(diào)排序
[java]?view plaincopy
數(shù)組b通過雙調(diào)排序排序。
[java] view plaincopy網(wǎng)絡:
例如,圖5展示了輸入長度為6的雙調(diào)排序網(wǎng)絡。
圖5:輸入長度為6的雙調(diào)排序網(wǎng)絡
分析:
這個對于任意n的新排序網(wǎng)絡可以嵌入原始的對于2^k的雙調(diào)排序網(wǎng)絡。因此,它仍有?log(n)?· (log(n)?+?1)?/?2 層,每層最多比較n/2次,結(jié)果是一個復雜度為O(nlog(n)^2)的比較器,跟原始的雙調(diào)排序網(wǎng)絡一樣。
總結(jié)
- 上一篇: linux读写二进制大文件
- 下一篇: gpu排序