Python中固定前一个元素的排列

时间:2012-01-13 04:26:01

标签: python permutation

所以我在列表中遇到了修复前一个元素的排列问题。所以,我有列表,这是从1到n的有序数字序列。

修改

这是我的问题的改革: 你能想象一个树形图吗?所以,第一级 - 它是一个顶级(也称为父级)顶点。所以,如果我们有像[1,2,3,4]这样的顶点,我们的下一步就是进行排列,将所有数字插入位置 n ,这意味着在输出中我们会有这个:

1.1 lvl [1, 2, 3, 4]

2.1 lvl [1, 2, 4, 3]

3.1 lvl [1, 3, 4, 2]

4.1 lvl [2, 3, 4, 1]

那么,我们看一下1.1级并使n-1元素的排列(4是固定的,不参与此级别的排列)。输出将是:

1.1.1 lvl [1, 2, 3, 4]

1.1.2 lvl [1, 3, 2, 4]

1.1.3 lvl [2, 3, 1, 4]

我们使用了1.1.1 lvl并修复了n-2元素(正如您所看到的,没有必要修复第一个元素)。所以,在这个级别上,我们已经修复了34,它们是n-1n元素,其中包括:

1.1.1.1 lvl [1, 2, 3, 4]

1.1.1.2 lvl [2, 1, 3, 4]

我们在这里吃过饭,但还没完成。 lvl up(它的级别为1.1.2)。并置换它。在这里,我们修复了n-1元素(它是2)和n(它是4

1.1.2.1 lvl [1, 3, 2, 4]

1.1.2.2 lvl [3, 1, 2, 4]

在这里完成。 GOTO在上层。此处修复了14。所以,

1.1.3.1 lvl [2, 3, 1, 4]

1.1.3.2 lvl [3, 2, 1, 4]

我们已完成1.1级并进入2.1,我们重复相同的程序。

所以,问题是:如何在python中执行此操作?

5 个答案:

答案 0 :(得分:2)

您可以随时使用itertools.permutations

from itertools import permutations
perm = permutations([1, 2, 3, 4])
while True:
    try:
        print perm.next() # perm.next() gives a tuple of the next permutation
    except StopIteration:
        break

答案 1 :(得分:2)

结果中的排列与前一个元素的不同之处在于交换两个元素。

交换两个元素对应于一个permutohedron中的边。

这表明您正在尝试根据某些标准访问permutohedron中的顶点。你能解释几何术语的标准吗?

例如,一个可能的问题是如何通过在每个回合交换两个元素来生成所有可能的排列。这相当于在permutohedron上找到哈密顿路径。这个问题的答案由Steinhaus-Johnson-Trotter algorithm给出,它给出了一个O(n)方法,用于从给定位置找到下一个排列。

修改

以下是更新问题的一些Python代码:

def perms(A):
    if len(A)==1:
        yield A
    for i in xrange(len(A)-1,-1,-1):
        for B in perms(A[:i]+A[i+1:]):
            yield B+A[i:i+1]

运行

for a in perms([1,2,3,4]):
    print a

打印以下内容:

[1, 2, 3, 4]
[2, 1, 3, 4]
[1, 3, 2, 4]
[3, 1, 2, 4]
[2, 3, 1, 4]
[3, 2, 1, 4]
[1, 2, 4, 3]
[2, 1, 4, 3]
[1, 4, 2, 3]
[4, 1, 2, 3]
[2, 4, 1, 3]
[4, 2, 1, 3]
[1, 3, 4, 2]
[3, 1, 4, 2]
[1, 4, 3, 2]
[4, 1, 3, 2]
[3, 4, 1, 2]
[4, 3, 1, 2]
[2, 3, 4, 1]
[3, 2, 4, 1]
[2, 4, 3, 1]
[4, 2, 3, 1]
[3, 4, 2, 1]
[4, 3, 2, 1]

答案 2 :(得分:1)

我希望这是你想要的:我更喜欢使用indeces 0,1,2,3而不是1,2,3,4

def switch(a,b,c):
    aux = a[b]
    a[b] = a[c]
    a[c] = aux
class perm():
    def __init__(self,mylist,txt,myreference,flag = None):
        self.mylist = []
        self.mylist.extend(mylist)
        self.myreference = myreference
        self.txt = txt
        if flag == None:
            print self.mylist,txt
    def make_perm(self):
        count = 0
        if self.myreference > 1:
            New = perm(self.mylist,self.txt+str(count),self.myreference-1,0)
            New.make_perm()
        for i in xrange(self.myreference-1,-1,-1):
            switch(self.mylist,i,self.myreference)
            count += 1
            New = perm(self.mylist,self.txt+str(count),self.myreference-1)
            New.make_perm()

N = 4            
A = perm(range(N),"",N-1)
A.make_perm()

我希望你意识到,一旦我们在[1,2,4,3]并且我们将3固定在第4位置,就不能继续在1,4,2,3上移动permutohedron而不改变位置3.

答案 3 :(得分:0)

如果标准库解决方案由于某种原因不适合,我可以建议做一个递归函数,它处理排列。

暗示解决方案:

def perm(lst):
   if len(lst) == 1:  # single element list                                                                                                                                                           
       return [lst]

   res = []
   for last_item in lst:
       lst1 = filter(lambda x: x!= last_item, lst)  # ... without last_item                                                                                                                           
       for p in perm(lst1):                                                                                                                                                                
           res.append(p + [last_item])

   return res

我希望解决方案很简单。有一些方法可以优化它,使用生成器和惰性计算等。

答案 4 :(得分:0)

受彼得·德·里瓦兹(Peter de Rivaz)解决方案的启发,我们也可以采用这种方式。

import itertools as it
import numpy as np
for comb in it.combinations(np.arange(1,5), r=4):
    for comb_perm in it.permutations(comb, r=4):
        print(comb_perm)

这将导致

(1, 2, 3, 4)
(1, 2, 4, 3)
(1, 3, 2, 4)
(1, 3, 4, 2)
(1, 4, 2, 3)
(1, 4, 3, 2)
(2, 1, 3, 4)
(2, 1, 4, 3)
(2, 3, 1, 4)
(2, 3, 4, 1)
(2, 4, 1, 3)
(2, 4, 3, 1)
(3, 1, 2, 4)
(3, 1, 4, 2)
(3, 2, 1, 4)
(3, 2, 4, 1)
(3, 4, 1, 2)
(3, 4, 2, 1)
(4, 1, 2, 3)
(4, 1, 3, 2)
(4, 2, 1, 3)
(4, 2, 3, 1)
(4, 3, 1, 2)
(4, 3, 2, 1)

我已经在Fedora机器上测试了运行时间0.0029001235961914062。希望能有所帮助。

相关问题