2013-05-09 67 views
1

计算排列数目的最快方法是什么?我有以下问题:在Python中计算排序

首先我有这:

ncombos = itertools.combinations_with_replacement(['a1', 'a2', 'a3'], years*n) 
('a1', 'a1', 'a1') 
('a1', 'a1', 'a2') 
('a1', 'a1', 'a3') 
('a1', 'a2', 'a2') 
.... etc.....  
('a3', 'a3', 'a3') 

目的是要经过每一个,并计算每一个有排列的数量和构建具有这些值的阵列。我实现这一点使用:

nodes = np.ones(len(leafs)); i=0 #This will store the number of permutations 

for j in ncombos: 
    nodes[i] =len(list(set(itertools.permutations(np.asanyarray(j), n)))) 
    i = i+1 

np.asanyarray(j)的转换( 'A1', 'A1', 'A1')转换成正式[ 'A1', 'A1', 'A1'],这是需要排列()来工作。设置擦除相同的排列。列表列出了这个。 len计算我可以用a1,a1,a1进行多少置换。

所以基本上我想要的是统计排列的数量......但是我的代码非常棒!慢 !谢谢!

+1

你能有所正式定义你的问题?我不明白你想要计算什么。 – nhahtdh 2013-05-09 02:05:59

回答

8

使用数学。列表的排列数量是列表长度的阶乘,除以每个元素的多重性的阶乘的乘积(因为重复元素的集合被置换而没有效果)。

import operator 
from collections import Counter 
from math import factorial 
def npermutations(l): 
    num = factorial(len(l)) 
    mults = Counter(l).values() 
    den = reduce(operator.mul, (factorial(v) for v in mults), 1) 
    return num/den 

例子:

>>> npermutations([1,1,1]) 
1 
>>> npermutations([1,2,3]) 
6 
>>> npermutations([1,3,1,2,1,3,1,2]) 
420 
+0

我认为这是相似的,但不同于他想要计算的结果(假设我正确地认为他想要置换置换,又称笛卡尔积) – Patashu 2013-05-09 02:11:50

+0

他很清楚地想要置换的数量没有置换,但他计算对于每个组合都有替换。 (虽然,我有理由相信有一个替代方法来解决他的问题,不会引发组合爆炸......) – nneonneo 2013-05-09 02:13:17

+0

这就是我想要的!它工作完美。虽然我不知道为什么,但你的功能比我的方式快得多。任何线索?另外,你会如何让你的方法更快?有什么办法吗?谢谢! – Oniropolo 2013-05-09 02:20:31

0

如果你想要更换置换,这存在并被称为笛卡尔产品。 Itertools具有这样的功能,product()

>>> for i in itertools.product('ABC', repeat=3): 
...  print i 
... 
('A', 'A', 'A') 
('A', 'A', 'B') 
('A', 'A', 'C') 
('A', 'B', 'A') 
('A', 'B', 'B') 
('A', 'B', 'C') 
('A', 'C', 'A') 
('A', 'C', 'B') 
('A', 'C', 'C') 
('B', 'A', 'A') 
('B', 'A', 'B') 
('B', 'A', 'C') 
('B', 'B', 'A') 
('B', 'B', 'B') 
('B', 'B', 'C') 
('B', 'C', 'A') 
('B', 'C', 'B') 
('B', 'C', 'C') 
('C', 'A', 'A') 
('C', 'A', 'B') 
('C', 'A', 'C') 
('C', 'B', 'A') 
('C', 'B', 'B') 
('C', 'B', 'C') 
('C', 'C', 'A') 
('C', 'C', 'B') 
('C', 'C', 'C')