in src/alpaca_eval/utils.py [0:0]
def random_derangement(arr, max_loop=10, seed=None):
"""
Make random derangement of an array. I.e. shuffle without keeping any element in place. To be efficient,
we first try `max_loop` rejection sampling. If didn't work then computes all possible derangement.
"""
if len(arr) < 2:
return arr
rng = random.Random(seed)
idcs = list(range(len(arr)))
shuffled = list(range(len(arr)))
for _ in range(max_loop):
rng.shuffle(shuffled)
if is_derangement(idcs, shuffled):
return arr[shuffled]
# if no luck then computes all possibilities
deranged_order = list(set([s for s in itertools.permutations(idcs) if is_derangement(s, idcs)]))
return arr[list(rng.choice(deranged_order))]