Sorting Networks

算法导论第27章,在并行处理的条件下效率很高的排序算法。

介绍
如下面左图所示,每条横线(wire)代表一个待比较的数值,竖线(comparator)表示连接的两条横线要做一次比较,并将较小的值放在输出横线的上方,较大的放在下面。排序过程就是从左往右依次调用各个comparator(在同一位置上的comparator可以同时做)
有图表示了四个数字3, 2, 4, 1在经过这个Sorting Network时的行为。

下图是一个冒泡排序的Sorting Network表示

可以看到所有的比较都没有并行,效率很低。接下来先介绍一个0-1原理,然后利用它来构造一些比较高效的网络。

性质
首先是引理27.1:
对于输入数据A = <a_1, a_2, .., a_n>,如果某个比较网络(comparison network)的输出是B = <b_1, b_2, ..., b_n>,那么对于任一单调递增的函数f,这个网络能把输入数据f(A) = <f(a_1), f(a_2), ..., f(a_n)>变为f(B) = <f(b_1), f(b_2), ...f(b_3)>

这个引理的证明很简单,关键在于min(f(x), f(y)) = f(min(x,y))

接下来就是0-1原理:
一个有n个输入数据的比较网络,如果它能将仅由0和1组成的序列正确的排序(这种输入共有2^n种可能),那么它也能正确的将任意数字组成的序列排序。
证明也不难,利用前面的引理反正即可得到这个定理。

双调排序
接下来先考虑双调序列(bitonic sequence)这种特殊情况,所谓双调序列就是先单调递增,后单调递减,或者可以通过环形旋转变化出上述特性的序列,比如<1, 4, 6, 8, 3, 2>和<6, 9, 4, 2, 3, 5>都满足条件(对于后面一种序列,只要把最后的3, 5移到序列开头就行了)。
双调排序(bitonic sorter)有若干步骤,其中有一步叫做half-cleaner,每一次half-cleaner讲数据放到一个深度为1的排序网络中,第i行和第i+n/2行比较(i=1,2,..,n/2)
Sorting Networks_第1张图片
引理27.3:
做完上述的half-cleaner后,输出的上半部分和下半部分都保持双调的特点,而且上半部分的每个元素都不大于下半部分的任一元素。
分四种情况讨论即可。

通过递归调用half-cleaner即可完成双调队列的排序。要对n个元素进行双调排序Bitonic-Sorter(n),首先调用Half-Cleaner(n),将元素分成上下两部分,接着依次对这两部分执行Bitonic-Sorter(n/2)即可。
调用的深度D(n) = lgn

归并网络
书上只给出了对0-1序列排序的算法,任意数字的排序算法留作了习题。
合并网络基于这样一个事实:对于两个已经排序了的序列X = 00000111,Y = 00001111,将Y倒过来后和X拼接的结果是一个双调序列。对这个双调序列再做一次Bitonic-Sorter就能有序。
通过修改Bitonic-Sorter方法的第一步就能实现Merger,关键在于隐式的反转输入的下半部分。Half-Cleaner方法中比较了第i和第i+n/2两个元素,如果下半部分反转的话就相当于比较第i和第n-i+1个元素。直接继续执行Bitonic-Sorter方法即可,如下图所示。
sortnetwork.JPG

排序网络
我们已经有了构造一个排序网络所需的工具,接下来介绍一种利用归并网络进行排序的并行版本。
大致方法和传统的归并排序类似,从最小的颗粒开始二分增长,直到整个序列有序。
这样,一共需要lg(n)次Merger,每次归并中需要做lg(i)次Sorter,排序的总深度
D(n) =
0               (n = 1)
D(n/2) + lg(n)  (n = 2^k且 k>=1)
由Master Method可推出D(n) = big-omega(lg^2(n))
也就是说理想的并行环境中,n个数可以在O(lg^2(n))时间内完成排序。

Bitonic Sorter http://www.iti.fh-flensburg.de/lang/algorithmen/sortieren/bitonic/bitonicen.htm

你可能感兴趣的:(Sorting Networks)