如何在不构建临时列表的情况下计算唯一排列的数量?

时间:2014-10-15 14:33:46

标签: python math combinatorics

如何计算此数字而不是枚举所有排列,然后创建设置以切断所有重复?

len(set(itertools.permutations('aaabbb')))
20

len(set(itertools.permutations('aabb')))
6

2 个答案:

答案 0 :(得分:7)

令count为数组,其中[k] =第k个符号的计数。

我们需要一种方法让python轻松计算一系列乘法,即product()函数....

来自What's the Python function like sum() but for multiplication? product()?

from functools import reduce # Valid in Python 2.6+, required in Python 3
import operator

def product(X):
    return reduce(operator.mul, X, 1)

现在我们可以将排列数定义为:

def unique_permutations(counts):
    return math.factorial(sum(counts))/product(map(math.factorial, counts))

现在用另一种语言,人们不得不担心这个部门中出现的大数字是由于采用大因子或乘以许多较小的因子。通常,在某些时候,计算将溢出MAXINT或MAXFLOAT规范。但是在python中,所有整数运算都是精确的,占用了所需数量的数字,并且设计不会发生整数溢出。速度可能会成为一个问题,但这是另一回事。

如何使用它:

>>> unique_permutations([3,3])
20

>>> unique_permutations([2,2])
6

有关如何执行此操作的数学计算,请参阅Wikipedia: Permutation: Permutations of Multisets

答案 1 :(得分:2)

如果您有每个字母的N_i份,那么您想要的数字是multinomial coefficient

  

(N_1 + N_2 + ... + N_k)!/(N_1! N_2! ... N_k!)

对于没有溢出的计算方法,请参阅How do I compute multinomials efficiently?