Given a sequence a with n unique elements, I want to create a sequence b which is a randomly selected permutation of a such that there is at least a specified minimum distance d between duplicate elements of the sequence which is b appended to a.
For example, if a = [1,2,3] and d = 2, of the following permutations:
a b
[1, 2, 3] (1, 2, 3) mindist = 3
[1, 2, 3] (1, 3, 2) mindist = 2
[1, 2, 3] (2, 1, 3) mindist = 2
[1, 2, 3] (2, 3, 1) mindist = 2
[1, 2, 3] (3, 1, 2) mindist = 1
[1, 2, 3] (3, 2, 1) mindist = 1
b could only take one of the first four values since the minimum distance for the last two is 1 < d.
I wrote the following implementation:
import random
n = 10
alist = list(range(n))
blist = alist[:]
d = n//2
avail_indices = list(range(n))
for a_ind, a_val in enumerate(reversed(alist)):
min_ind = max(d - a_ind - 1, 0)
new_ind = random.choice(avail_indices[min_ind:])
avail_indices.remove(new_ind)
blist[new_ind] = a_val
print(alist, blist)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 3, 2, 8, 5, 6, 4, 0, 9, 7]
but I think this is n^2 time complexity (not completely sure). Here's a plot of the time required as n increases for d = n//2:
Is it possible to do better than this?
