简体   繁体   中英

How to calculate the number of unique permutations without building a temporary list?

How to calculate this number instead of enumerate all permutations and then create set to cut off all repetitions?

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

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

Let counts be an array with counts[k] = count of the k'th symbol.

We'll need a way for python to easily compute a bunch of multiplications, a product() function....

From 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)

Now we can define the number of permutations as:

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

Now in another language, one would have to worry about the large numbers that can appear in this division as the result of taking large factorials or multiplying numerous smaller factorials. Normally, at some point the calculation will overflow a MAXINT or MAXFLOAT spec. But in python, all integer operations are exact, taking as many digits as required, and integer overflow will not occur by design. Speed might become an issue, but that is a different matter.

How to use it:

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

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

For the math of how to do this, see Wikipedia: Permutation: Permutations of Multisets

If you have N_i copies of each letter then the number you want is the multinomial coefficient

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

For methods for computing this without overflow, see How do I compute multinomials efficiently? .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM