我在做,可以生成元素的列表,并置换为基础的原始名单上签名的所有排列代码。
一般而言排列的数量由第一种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]有没有产生置换及其标志更有效的方法?
是的,你的方法是正确的。而不是直接证明这一点,你应该证明
(1)permute(a, l, r)
的执行返回的每个排列的l
次,直到恰好一次r
的a
个字母和退出时a
等于它是在执行开始。
这是简单的通过感应上r - l
证明。如果没有“退出时a
等于”索赔的一部分,这将是很难。
至于标志是正确的,这仅仅是一个循环不变:你交换两种不同的条目时,你都乘以-1的符号,而这些都是你改变标志的唯一时间。所以,是的,第0项是排列在你的过程中每次的迹象。
Knuth的TAOCP(卷4A)都有专门算法生成所有排列第7.2.1.2。他们中有些人可以很容易地修改,以生成自己的招牌了。我想知道,如果你是其中之一。