Problem:
Somebody is generating permutations of a given list of elements in a lexicographical order. What is the value of say nth permutation?
Brute force solution is to generate them all, but in that case you'll spend quite a lot of time generating useless permutations - O(n!). So here is the easy way:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/env python | |
""" | |
Solves a problem of getting permutation of a given index, | |
while you know that permutations are created in a lexicographical order. | |
As input you are specifying a list of elements and index of permutation you want to get. | |
""" | |
## imports | |
from math import factorial | |
## this one just for checking | |
from itertools import permutations | |
def getNthPermutation( pIndex, inList, outList=[] ): | |
""" get :pIndex: permutation of :inList: | |
:warn: permutations are sorted in lexicographical order starting from 0, i.e.: | |
0 -> [1, 2, 3], 1 -> [1, 3, 2] and so on | |
:param int pIndex: given permutation index | |
:param list inList: initial list of elements | |
:param list outList: result list | |
""" | |
## permutation index too big | |
if pIndex >= factorial( len(inList) ): return [] | |
## no more elements to use | |
if not inList: return outList | |
## make sure eList is sorted | |
inList.sort() | |
## get factorial | |
f = factorial( len(inList)-1 ) | |
index = pIndex / f | |
reminder = pIndex % f | |
## add new element to outList | |
outList.append( inList[index] ) | |
## ...and remove it from inList | |
del inList[index] | |
## bail out or call recursively depending of the reminder | |
if not reminder: | |
return outList + inList | |
else: | |
return getNthPermutation( reminder, inList, outList ) | |
### test execution | |
if __name__ == "__main__": | |
ps = permutations( [1,2,3,4,5,6] ) | |
for i in range(factorial(6)): | |
resList = [] | |
res = getNthPermutation( i, [1,2,3,4,5,6], resList ) | |
check = list( ps.next() ) | |
assert( res == check ) |
Brak komentarzy:
Prześlij komentarz