-
Notifications
You must be signed in to change notification settings - Fork 0
/
random_permutation.py
48 lines (38 loc) · 1.45 KB
/
random_permutation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import copy
import functools
import math
import random
from test_framework import generic_test
from test_framework.random_sequence_checker import (
check_sequence_is_uniformly_random, run_func_with_retries)
from test_framework.test_utils import enable_executor_hook
def compute_random_permutation(n):
perm = list(range(n))
perm[:] = random.sample(perm, n)
return perm
@enable_executor_hook
def compute_random_permutation_wrapper(executor, n):
def compute_random_permutation_runner(executor, n):
def permutation_index(perm):
p = copy.deepcopy(perm)
idx = 0
n = len(p)
while p:
a = p.pop(0)
idx += a * math.factorial(n - 1)
for i, b in enumerate(p):
if b > a:
p[i] -= 1
n -= 1
return idx
result = executor.run(
lambda: [compute_random_permutation(n) for _ in range(1000000)])
return check_sequence_is_uniformly_random(
[permutation_index(perm)
for perm in result], math.factorial(n), 0.01)
run_func_with_retries(
functools.partial(compute_random_permutation_runner, executor, n))
if __name__ == '__main__':
exit(generic_test.generic_test_main("random_permutation.py",
'random_permutation.tsv',
compute_random_permutation_wrapper))