I\'m reading about permutations and I\'m interested in ranking/unranking methods.
From the abstract of a paper:
A ranking function for the per
One way is to rank and unrank the choice of indices by a particular group of equal numbers, e.g.,
def choose(n, k):
c = 1
for f in xrange(1, k + 1):
c = (c * (n - f + 1)) // f
return c
def rank_choice(S):
k = len(S)
r = 0
j = k - 1
for n in S:
for i in xrange(j, n):
r += choose(i, j)
j -= 1
return r
def unrank_choice(k, r):
S = []
for j in xrange(k - 1, -1, -1):
n = j
while r >= choose(n, j):
r -= choose(n, j)
n += 1
S.append(n)
return S
def rank_perm(P):
P = list(P)
r = 0
for n in xrange(max(P), -1, -1):
S = []
for i, p in enumerate(P):
if p == n:
S.append(i)
S.reverse()
for i in S:
del P[i]
r *= choose(len(P) + len(S), len(S))
r += rank_choice(S)
return r
def unrank_perm(M, r):
P = []
for n, m in enumerate(M):
S = unrank_choice(m, r % choose(len(P) + m, m))
r //= choose(len(P) + m, m)
S.reverse()
for i in S:
P.insert(i, n)
return tuple(P)
if __name__ == '__main__':
for i in xrange(60):
print rank_perm(unrank_perm([2, 3, 1], i))