您的位置:首页 > 其它

#算法证明#证明字典序全排列生成算法及实现

2016-10-23 15:30 423 查看

缘起

在网上看到了字典序全排列生成算法,不懂为什么会这样可以算法可以生成当前序列的下一个字典序,于是便在思考能不能证明一下。

step1:

对于排列a[0...n−1] ,找到所有满足a[k]<a[k+1](−1<k<n−2) 的k的最大值,如果这样的k不存在,则说明当前排列已经是a的所有排列中字典序最大者,所有排列输出完毕。

step2:

在a[k+1...n] 中,寻找满足这样条件的元素l,使得在所有a[l]>a[k] 的元素中,a[l]取得最小值。也就是说a[l]>a[k] ,但是小于所有其他大于a[k]的元素。

step3:

交换a[l] 与a[k] .

step4:

对于a[k+1...n] ,反转该区间内元素的顺序。也就是说a[k+1]与a
交换,a[k+2]与a[n-1]交换,……,这样就得到了a[1…n]在字典序中的下一个排列。

预备知识

首先要了解什么是字典序:

设想一本英语字典里的单词,何者在前何者在后?

显然的做法是先按照第一个字母、以 a、b、c……z 的顺序排列;如果第一个字母一样,那么比较第二个、第三个乃至后面的字母。如果比到最后两个单词不一样长(比如,sigh 和 sight),那么把短者排在前。(维基百科)

如果你不满足于上面的简单理解,可以看在wikipedia的严格定义

开始证明

首先对于一个字符串,每一个字符可能为c1、c2、c3……cm的m个有序字符中的一个。我们定义:

其中任意两个字符a、b的相减运算,记为“a−b”,的结果为他们的顺序数相减

例如c3 - c1 = 第3个 - 第1个= 2.

假设我们现在又有两个长度为n的字符串A、B,其中A、B的每个字符有m种可能。定义:

字符串A、B的距离d(A,B)=∑ i=0 n−1 (A i −B i )∗m n−1−i

显然,我们要证明字典序全排列生成算法有效,即此算法能生成的A的下一个字典序全排列,则需证明d(A next ,A)>0且d(A next ,A)=min{d(任一大于A的全排列,A)},其中A next 是此算法生成的A的下一个字典序全排列(∗)

证明step1

要使(*)成立,则A的某一位A k 则必须被替换为A j , 其中A j >A k 且j>k 这样生成的A next 才会使d(A next ,A)>0 .

又因为d(A next ,A) 尽量小,所以A k 必须是序列A中满足A i <A i+1 的下标最大(即最右边)的一个。这用反证法根据d(A,B) 的定义可以证明。如找不到这样的A i 说明A已经没有下一个更大的字典序全排列了。

证明step2和step3

step1后,A next 0 A next 1 ……A next k−1 都确定了,即A 0 A 1 ……A k−1 ,否则d(A next ,A) 将变大。我们此时能动的是A k A k+1 ……A n−1 。

已知A k 要被调换,为了使d(A next ,A) 尽量小,A k 应该被调换为A k+1 ……A n−1 中最小的一个。这用反证法根据d(A,B) 的定义可以证明。

证明step4

step2和step3后,A next k 位置也被固定。还能动的是A k+1 ……A n−1

我们注意到,在step1中:因为A k 必须是序列A中满足A i <A i+1 的下标最大(即最右边)的一个,A k+1 到A n−2 都不符合这个性质,所以序列A k+1 ……A n−1 是非递增的

显然,经过step2和step3后的A k+1 ……A n−1 仍然是非递增的。

由于step2,step3已经保证d(A next ,A)>0 ,我们只需要重排A i+1 ……A n−1 来使d(A next ,A) 尽量小,即∑ i=k+1 n−1 (A next i −A i )∗m n−1−i 尽量小。

上面说了:序列A k+1 ……A n−1 是非递增的,所以我们只要将序列A k+1 ……A n−1 逆转,便可以使上式最小。这样子权重越大,系数越小,从而保证上式最小。

这样

A next k+1 A next k+2 ……A next n−1 也确定了,它们是A n−1 A n−2 ……A k+1 。

结论

最终A next 的每一个字符都被确定下来,并且(*)成立,这说明上述算法确实是有效的。

思考

证明的时候进一步发现这个算法的思路是,在保证(*)成立的前提下,逐渐确定A next 的每一个字符,最终确定了A next 的所有字符,所得出得字典序全排列便是我们想要的。

这是局部最优达到全局最优的一个典型例子。

实现

具体实现在我的另一篇博客中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法证明