是否有用于生成序列的所有排列的递归算法的证明?

时间:2013-11-27 21:13:50

标签: algorithm math

为清楚起见,我在Python下面附上了一个简洁的算法实现。我理解它检查所有可能的元素交换,但我不明白这是如何必然意味着将达到所有可能的元素排序,和/或不会重复排序。

例如,如果交换了索引0和1处的元素,那么交换1和2会怎样?算法如何保证这不会导致重复排序?

P = []
def permute(l, n=0):
    if n == len(l):
        return P.append(list(l))
    for i in xrange(n, len(l)):
        l[i], l[n] = l[n], l[i]
        permute(l, n+1)
        l[i], l[n] = l[n], l[i]

1 个答案:

答案 0 :(得分:1)

假设:取一组“m”个不同的对象(序列的元素)。 取初始序列为l = [a1,a2,a3,...,am]。

命题:上面给出的算法产生“m!”不同的序列。

证明:取“n = 0”和一些i。第一步是交换l [i]和l [n]。

观察:当调用“permute(l,n)”时,索引j = {0,1,...,n - 1}处的“l”值保持不变。

注意到这一观察结果。当调用permute(l,0)时,我们最终得到“m”非重叠序列集。每组中序列的共同特性是它们都以l [0]的相同值开始,例如a1,a2,...,am。 将A [i = j,n = 0]作为在用l [i = j]交换l [n = 0]之后获得的所有这样的序列的集合。因为对于不同的“j”,集合不重叠,所获得的总序列等于 N_total = n(A [0,0])+ n(A [1,0])+ ... + n(A [m - 1,0])。

由于l [0]在“permute(l,1)”的调用中不会改变,因此相当于“permute(l',0)”,其中“l”是由“l”获得的“l”的子序列删除“l [0]”。 类似的论证导致在该调用中获得“m-1”非重叠序列子集。即,A [i,0]又将是“m-1”个非重叠集的并集。通过归纳,最终的结果将是m的联合!非重叠集。由于每个集合都是非空的(通过检查n == len(l)的情况在算法中得到保证),那么将至少为m!不同的产出。

另一方面,最多可以有m!因此,不同的排列,算法的输出将是m!不同的序列。

最后,请注意,如果按值传递列表,此参数可以在上方应用,我相信在Python中就是这种情况。希望它有所帮助。