Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,86 @@
from math import factorial as fact
from random import randrange
from textwrap import wrap
def identity_perm(n):
return list(range(n))
def unranker1(n, r, pi):
while n > 0:
n1, (rdivn, rmodn) = n-1, divmod(r, n)
pi[n1], pi[rmodn] = pi[rmodn], pi[n1]
n = n1
r = rdivn
return pi
def init_pi1(n, pi):
pi1 = [-1] * n
for i in range(n):
pi1[pi[i]] = i
return pi1
def ranker1(n, pi, pi1):
if n == 1:
return 0
n1 = n-1
s = pi[n1]
pi[n1], pi[pi1[n1]] = pi[pi1[n1]], pi[n1]
pi1[s], pi1[n1] = pi1[n1], pi1[s]
return s + n * ranker1(n1, pi, pi1)
def unranker2(n, r, pi):
while n > 0:
n1 = n-1
s, rmodf = divmod(r, fact(n1))
pi[n1], pi[s] = pi[s], pi[n1]
n = n1
r = rmodf
return pi
def ranker2(n, pi, pi1):
if n == 1:
return 0
n1 = n-1
s = pi[n1]
pi[n1], pi[pi1[n1]] = pi[pi1[n1]], pi[n1]
pi1[s], pi1[n1] = pi1[n1], pi1[s]
return s * fact(n1) + ranker2(n1, pi, pi1)
def get_random_ranks(permsize, samplesize):
perms = fact(permsize)
ranks = set()
while len(ranks) < samplesize:
ranks |= set( randrange(perms)
for r in range(samplesize - len(ranks)) )
return ranks
def test1(comment, unranker, ranker):
n, samplesize, n2 = 3, 4, 12
print(comment)
perms = []
for r in range(fact(n)):
pi = identity_perm(n)
perm = unranker(n, r, pi)
perms.append((r, perm))
for r, pi in perms:
pi1 = init_pi1(n, pi)
print(' From rank %2i to %r back to %2i' % (r, pi, ranker(n, pi[:], pi1)))
print('\n %i random individual samples of %i items:' % (samplesize, n2))
for r in get_random_ranks(n2, samplesize):
pi = identity_perm(n2)
print(' ' + ' '.join('%2i' % i for i in unranker(n2, r, pi)))
print('')
def test2(comment, unranker):
samplesize, n2 = 4, 144
print(comment)
print(' %i random individual samples of %i items:' % (samplesize, n2))
for r in get_random_ranks(n2, samplesize):
pi = identity_perm(n2)
print(' ' + '\n '.join(wrap(repr(unranker(n2, r, pi)))))
print('')
if __name__ == '__main__':
test1('First ordering:', unranker1, ranker1)
test1('Second ordering:', unranker2, ranker2)
test2('First ordering, large number of perms:', unranker1)

View file

@ -0,0 +1,104 @@
from random import randrange
from typing import List
Perm = List[int]
_fact = [1] # factorials cache
def print_perm(T: Perm) -> None:
print(T)
def tj_unrank(n: int, r: int) -> Perm:
"Returns the r-ranked Trotter-Johnson permutation of integers 0..n-1"
global _fact
for i in range(len(_fact), n+2): # Extend factorial cache if necessary.
_fact.append(_fact[i - 1] * i)
pi: Perm = [0] * (n+2)
pi[1] = 1
r2 = 0
for j in range(2, n+1):
r1 = (r * _fact[j]) // _fact[n]
k = r1 - j*r2
if ((r2 % 2) == 0):
for i in range(j-1, j - k - 1, -1):
pi[i+1] = pi[i]
pi[j-k] = j
else:
for i in range(j - 1, k, -1):
pi[i+1] = pi[i]
pi[k + 1] = j
r2 = r1
return [i - 1 for i in pi[1:-1]]
def tj_rank(p: Perm) -> int:
"Returns the ranking of the Trotter-Johnson permutation p, of integers 0..n-1"
n = len(p)
assert set(p) == set(range(n)), f"Perm {p} not a perm of 0..{n-1}."
pi = [0] + [i+1 for i in p] + [0]
r = 0
for j in range(2, n + 1):
i = k = 1
while pi[i] != j:
if (pi[i] < j):
k += 1
i += 1
if ((r % 2) == 0 ):
r = j*r+j-k
else:
r = j*r+k-1
return r
def tj_parity(p: Perm) -> int:
"Returns the 0/1 parity of the Trotter-Johnson permutation p, of integers 0..n-1"
n = len(p)
assert set(p) == set(range(n)), f"Perm {p} not a perm of 0..{n-1}."
pi = [0] + [i+1 for i in p] + [0]
a, c = [0] * (n + 1), 0
for j in range(1, n+1):
if a[j] == 0:
c += 1
a[j] = 1
i = j
while ( pi[i] != j ):
i = pi[i]
a[i] = 1
return (n-c) % 2
def get_random_ranks(permsize, samplesize, fact):
perms = fact[permsize]
ranks = set()
while len(ranks) < samplesize:
ranks |= set( randrange(perms)
for r in range(samplesize - len(ranks)) )
return ranks
if __name__ == '__main__':
n = 3
print(f"Testing rank/unrank n={n}.\n");
for i in range(len(_fact), n+2): # Extend factorial cache if necessary.
_fact.append(_fact[i - 1] * i)
for r in range(_fact[n]):
p = tj_unrank(n, r)
rank = tj_rank(p)
parity = tj_parity(p)
print(f" Rank: {r:4} to perm: {p}, parity: {parity} back to rank: {rank}")
for samplesize, n2 in [(4, 12), (3, 144)]:
print('\n %i random individual samples of %i items:' % (samplesize, n2))
for i in range(len(_fact), max([n, n2])+2): # Extend factorial cache if necessary.
_fact.append(_fact[i - 1] * i)
for r in get_random_ranks(n2, samplesize, _fact):
p = tj_unrank(n2, r)
rank = tj_rank(p)
parity = tj_parity(p)
print(f" Rank: {r:10} to perm: {p}, parity: {parity} to rank: {rank:10}")

View file

@ -0,0 +1,17 @@
def ranker1(n, pi, pi1):
if n == 1:
return 0
n1 = n-1
s = pi[n1]
pi[n1], pi[pi1[n1]] = pi[pi1[n1]], pi[n1]
pi1[s], pi1[n1] = pi1[n1], pi1[s]
return s + n * ranker1(n1, pi, pi1)
def ranker2(n, pi, pi1):
result = 0
for i in range(n-1, 0, -1):
s = pi[i]
pi[i], pi[pi1[i]] = pi[pi1[i]], pi[i]
pi1[s], pi1[i] = pi1[i], pi1[s]
result += s * fact(i)
return result