Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

produce a random subset of all permutations

I'm looking for a way to randomly sample a fixed length subset of all permutations.

import itertools
from random import shuffle

mylist = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T']

APPROACH A

Approach A below suffers from the problem that the permutations are too similar.

a_pre = itertools.permutations(mylist,20)
a = itertools.islice(a_pre,3)

list(a)

['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T']

['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'T', 'S']

['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'S', 'R', 'T']

APPROACH B

Approach B gets me closer to my desired outcome, but here there's always a risk of producing identical ordering between lists, so this approach is not feasible.

#repeat n=3 times

shuffle(mylist)
print(mylist)

['J', 'B', 'M', 'A', 'O', 'C', 'K', 'S', 'H', 'Q', 'N', 'T', 'R', 'D', 'G', 'P', 'I', 'E', 'F', 'L']

['R', 'O', 'C', 'I', 'G', 'E', 'Q', 'L', 'P', 'J', 'F', 'N', 'A', 'B', 'H', 'T', 'D', 'K', 'M', 'S']

['L', 'O', 'I', 'G', 'B', 'E', 'R', 'A', 'D', 'N', 'J', 'S', 'H', 'F', 'K', 'M', 'Q', 'T', 'C', 'P']

like image 964
themachinist Avatar asked Mar 06 '23 22:03

themachinist


1 Answers

but here there's always a risk of producing identical ordering between lists, so this approach is not feasible.

You can use tuples (since lists aren't hashable) and sets (so that there are no duplicates/identical lists) to get around this:

from random import shuffle

mylist = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T']
myset = set()
while len(myset) < 5: #change 5 to however many you want
     shuffle(mylist)
     myset.add(tuple(mylist))
print([list(x) for x in myset])

Edit: As @tobias_k points out:

For the given list, there are 20! = 2432902008176640000 different permutations, so collisions are really very unlikely.

like image 101
Sean Breckenridge Avatar answered Mar 20 '23 05:03

Sean Breckenridge