堆的算法置换签名

问题描述 投票:1回答:1

我在做,可以生成元素的列表,并置换为基础的原始名单上签名的所有排列代码。

一般而言排列的数量由第一种Stirling数给定为K = N的组合物 - 该分区的n个元素C-循环。

       [n]           [n - 1]   [n - 1]
       [ ] = (n - 1) [     ] + [     ]
       [k]           [  k  ]   [k - 1]

的方式分割的n个元素为k周期的数目是分区N - 在最大元素在n的一个1非最大元素为k周期和拼接 - 1点的方式或将最大元件在其自己的循环和分区n个 - 1非最大元素为k - 1个周期。然后,符号将(-1)^ N-C给出,其中N是索引的数目,C是,当元件被从它们的原始位置移动形成循环的数量。

我已经编写了堆算法的变化能产生每个排列的签名。

    def permute(a, l, r): 
        if l==r:          
            print'Permutation--:',a
        else: 
            for i in xrange(l,r+1): 
                if i!=l:
                    a[0]=(-1)*int(a[0])#Sign for permutation
                a[l], a[i] = a[i], a[l] 
                permute(a, l+1, r)             
                a[l], a[i] = a[i], a[l]                         
                if i!=l:#Sign for permutation
                    a[0]=(-1)*int(a[0])




    test = "1hgfe"
    n = len(test) 
    a = list(test) 
    permute(a, 1, n-1)

在该例程中置换列表中的一个被引入该列表的第一部件上的[0]为符号在这种情况下是+1和用于每个排列,该列表的Sing是乘以-1。到目前为止,我觉得代码工作,这是测试的结果。

          ['1', 'h', 'g', 'f', 'e']  (h->h) (g->g) (f->f) (e->e)       (-1)^(4-4) or identity =+1  
          [-1, 'h', 'g', 'e', 'f']   (h->h) (g->g) (f->e)              (-1)^(4-3)=-1
          [-1, 'h', 'f', 'g', 'e']   (h->h) (g->f) (e->e)              (-1)^(4-3)=-1
          [1, 'h', 'f', 'e', 'g']    (h->h) (g->f->e)                  (-1)^(4-2)=+1
          [-1, 'h', 'e', 'f', 'g']   (h->h) (g->e) (f->f)              (-1)^(4-3)=-1
          [1, 'h', 'e', 'g', 'f']    (h->h) (g->e->f)                  (-1)^(4-2)=+1
          [-1, 'g', 'h', 'f', 'e']   (h->g) (f->f) (e->e)              (-1)^(4-3)=-1
          [1, 'g', 'h', 'e', 'f']    (h->g) (f->e)                     (-1)^(4-2)=+1
          [1, 'g', 'f', 'h', 'e']    (h->g->f) (e->e)                  (-1)^(4-2)=+1
          [-1, 'g', 'f', 'e', 'h']   (h->g->f->e)                      (-1)^(4-1)=-1
          [1, 'g', 'e', 'f', 'h']    (h->g->e) (f->f)                  (-1)^(4-2)=+1
          [-1, 'g', 'e', 'h', 'f']   (h->g->e->f)                      (-1)^(4-1)=-1
          [-1, 'f', 'g', 'h', 'e']   (h->f) (g->g)(e->e)               (-1)^(4-3)=-1
          [1, 'f', 'g', 'e', 'h']    (h->f->e) (g->g)                  (-1)^(4-2)=+1
          [1, 'f', 'h', 'g', 'e']    (h->f->g) (e->e)                  (-1)^(4-2)=+1
          [-1, 'f', 'h', 'e', 'g']   (h->f->e->g)                      (-1)^(4-1)=-1
          [1, 'f', 'e', 'h', 'g']    (h->f) (g->e)                     (-1)^(4-2)=+1
          [-1, 'f', 'e', 'g', 'h']   (h->f->g->e)                      (-1)^(4-1)=-1
          [-1, 'e', 'g', 'f', 'h']   (h->e) (g->g) (f->f)              (-1)^(4-3)=-1
          [1, 'e', 'g', 'h', 'f']    (h->e->f) (g->g)                  (-1)^(4-2)=+1
          [1, 'e', 'f', 'g', 'h']    (h->e) (g->f)                     (-1)^(4-2)=+1
          [-1, 'e', 'f', 'h', 'g']   (h->e->g->f)                      (-1)^(4-1)=-1
          [1, 'e', 'h', 'f', 'g']    (h->e->g) (f->f)                  (-1)^(4-2)=+1
          [-1, 'e', 'h', 'g', 'f']   (h->e->f->g)                      (-1)^(4-1)=-1  

我的问题是:你认为我的代码将适用于任何列表大小,即[1,A,B,C ......,Z_n]有没有产生置换及其标志更有效的方法?

python permutation combinatorics parity
1个回答
0
投票

是的,你的方法是正确的。而不是直接证明这一点,你应该证明

(1)permute(a, l, r)的执行返回的每个排列的l次,直到恰好一次ra个字母和退出时a等于它是在执行开始。

这是简单的通过感应上r - l证明。如果没有“退出时a等于”索赔的一部分,这将是很难。

至于标志是正确的,这仅仅是一个循环不变:你交换两种不同的条目时,你都乘以-1的符号,而这些都是你改变标志的唯一时间。所以,是的,第0项是排列在你的过程中每次的迹象。

Knuth的TAOCP(卷4A)都有专门算法生成所有排列第7.2.1.2。他们中有些人可以很容易地修改,以生成自己的招牌了。我想知道,如果你是其中之一。

© www.soinside.com 2019 - 2024. All rights reserved.