排序网络 Sorting Network - matrix67
1、比较器与排序网络
一般的排序算法都是给定了数据再排序,排序效率很大程度上取决于数据的好坏。我们今天所介绍的是一个完全不同的排序方法,它可以在“暗箱”里对数据进行排序(即你不必知道实际数据是什么),换句话说这种排序方法不依赖于数据(Data-Independent),所有比较操作都与数据无关。你甚至可以立即忘掉前面的比较结果,因为对于所有可能的数据这类排序算法都能得到正确答案并且排序步骤完全相同。本文结束后再回过头来看这段话你将有更深的认识。
我们设置一个暗箱,暗箱左边有n个输入口,暗箱右边有n个输出口。我们需要设计一个暗箱使得,任意n个数从左边输进去,右边出来的都是有序的。图1显示了有4个输入的暗箱。
暗箱里唯一允许的元件叫做“比较器”(Comparator),每个比较器连接两个元素,当上面那个比下面那个大时它将交换两个元素的位置。也就是说,每经过一个比较器后,它的两端中较小的一个总是从上面出来,较大的总是到了下面。
图2显示了一种包含4个比较器的暗箱系统。当输入数据 3,1,4,2 通过这个系统时,输出为1,3,2,4,如图3所示。这种暗箱结构叫做比较网络(Comparator Network)。如果对于任意一个输入数据,比较网络的输出都是有序的,那么这个比较网络就叫做排序网络(Sorting Network)。显然,我们例子中的比较网络不是一个排序网络,因为它不能通过 3,1,4,2 的检验。
冒泡排序是一个彻头彻尾的排序网络模型。它的比较就是无条件的,不管数据怎样冒泡排序都是不断比较相邻元素并把较小的放到前面。如图4。我们通常不认为插入排序是排序网络,因为插入排序的比较次数取决于数据的有序程度。
传统的计算机一次只能处理一个比较。排序网络真正的研究价值在于,假如有机器可以同时处理多个比较器,排序的速度将大幅度提高。我们把比较器的位置稍微移动一下,把那些互不冲突(处理的元素不同)的比较器压缩到一层(Stage)(图5),这样整个排序过程压缩为了 2n-3
层,图4为 n(n-1)/2
层。
我们自然又想,排序网络需要的层数能否少于 2n-3
。我们想到,图5的左下角和右下角似乎有些空,我们期望能在这些位置加一些比较从而减少层数。图6给出了一个只有 n
层的排序网络,这叫做奇偶移项排序(Odd-even Transposition Sort)。我们下文将证明它确实是一个排序网络。(图6的排序安排类似三阶矩阵求行列式的一种方法 Sarrus 规则)
2、0-1原理
给出一个比较网络,怎样判断它是不是一个排序网络?
传统的做法是枚举所有 n
的排列来验证,一共要考虑 n!
种情况。
下面我们介绍排序网络理论里最重要的结论:0-1原理( 0-1 Principle)。使用这个原理来验证排序网络只需要考虑 2^n
种情况。(言外之意:2^n < n!
)
0-1原理告诉我们,如果所有的01序列能够通过比较网络排出顺序,那么这足以说明该网络为排序网络。证明过程很简单。为了证明这个结论,我们证明它的逆否命题(逆否命题与原命题同真假,离散数学用在这😂):如果一个比较网络不是排序网络,那么至少存在一个01序列不能被排序。我们给出一种算法,这个算法可以把任何一个不能被排序的输入数据转化为一个不能被排序的01序列。
在最初的例子(图3)中,输入数据 3,1,4,2 的输出为 1,3,2,4,没有成功地排出顺序,从而判断出该网络不是排序网络。这说明,输出结果中存在逆序对(左边某个数大于右边的某个数)。我们从输出结果中找出一个逆序对来。例子中,(3,2) 就是我们要找的逆序对。现在,我们把输入中所有小于数字3(左边那个数)的数都变成0,把所有大于等于3的数都变成1(根据逆序对设置阈值)。这样,3,1,4,2 就变成了 1,0,1,0。显然,把得到的这个01序列输入进去,原来曾经发生过交换的地方现在仍然会交换,原来不曾交换的地方现在也同样不会发生交换(当两个0或两个1进行比较时,我们既可以认为它们不交换,也可以看成它们要互相交换,反正都一样)。最后,该01序列输出的结果中,本来3的位置现在还是1,原来2的位置现在仍然是0,逆序对仍然存在。因此,只要一个比较网络不是排序网络,那么总可以找到一个01序列不能被排序。等价地,如果所有的01序列都能被排序了(没有逆序对),这个比较网络也就是排序网络了。
3、证明奇偶移项排序的正确性
我们用 0-1原理 来证明奇偶移项排序的正确性。
我们对 n 进行数学归纳证明。
- n=2 时(一个“工”字)显然是排序网络。
- 图7中是n=8的情况。我们假设对于所有n<=7,奇偶移项排序网络都是正确的。我们同时假定所有输入数字非0即1,下面我们说明n=8时所有的01序列都能被正确排序。
假设最后一个数是1(图7),那么这个1将始终排在最后不参与任何交换操作,对前面7个数没有任何影响。除去无用的灰色部分,剩下的就是n=7这一规模较小的子排序网络,由归纳假设则n=8也是排序网络;
假设最后一个数是0(图8),那么在每一次比较中这个0都会被提到前面去(前面说过,两个0之间交不交换是一回事)。蓝色的箭头表示每个数跑到了什么位置。你会发现除最后一个数以外前7个数之间的比较器又构成了n=7的情况。
综上,奇偶移项排序是排序网络。