j'ai un tableau de 27 éléments, et je ne veux pas générer toutes les permutations de tableau (27!), j'ai besoin de 5000 permutations choisies au hasard, toute astuce sera utile ...
Pour générer une permutation, utilisez random.shuffle
et stockez une copie du résultat. Répétez cette opération en boucle et vérifiez à chaque fois qu'il y a des doublons (il n'y en aura probablement pas). Lorsque vous avez 5 000 éléments dans votre jeu de résultats, arrêtez-vous.
Pour traiter ce point dans le commentaire, le module random de Python est basé sur le Mersenne Twister et a une période de 2**19937-1
, ce qui est considérablement plus grande que 27!
et devrait donc vous convenir.
import random
perm_list = []
for i in range(5000):
temp = range(27)
random.shuffle(temp)
perm_list.append(temp)
print(perm_list)
10888869450418352160768000000
J'aime les gros chiffres! :)
ET
10888869450418352160768000001
is PRIME !!
MODIFIER:
#with duplicates check as suggested in the comment
perm_list = set()
while len(perm_list)<5000:
temp = range(27)
random.shuffle(temp)
perm_list.add(Tuple(temp)) # `Tuple` because `list`s are not hashable. right Beni?
print perm_list
AVERTISSEMENT: Cela ne s'arrêtera jamais si RNG est mauvais!
itertools.permutations
. C'est un générateur, donc il ne créera pas la liste complète des permutations. Vous pouvez sauter au hasard jusqu'à ce que vous ayez 5000.
# apermindex should be a number between 0 and factorial(len(alist))
def perm_given_index(alist, apermindex):
for i in range(len(alist)-1):
apermindex, j = divmod(apermindex, len(alist)-i)
alist[i], alist[i+j] = alist[i+j], alist[i]
return alist
Usage: perm_given_index(['a','b','c'], 3)
Ceci utilise le code de Lehmer pour la permutation car les valeurs de j
correspondent à cela.
Vous voudrez peut-être la fonction itertools.permutations (). Je dois aimer ce module itertools!
NOTE: Nouveau dans 2.6
Vous pouvez essayer d'implémenter les recettes random_permutation
itertools . Pour plus de commodité, j'utilise une bibliothèque tierce, more_itertools
, qui implémente cette recette pour nous:
import more_itertools as mit
iterable = range(27)
mit.random_permutation(iterable)
# (24, 3, 18, 21, 17, 22, 14, 15, 20, 8, 4, 7, 13, 6, 25, 5, 12, 1, 9, 19, 23, 11, 16, 0, 26, 2, 10)
Une permutation aléatoire est créée pour chaque appel de la fonction. Nous pouvons créer un générateur qui génère ces résultats pour les appels n
. Nous allons implémenter ce générateur et démontrer des résultats aléatoires avec un exemple abrégé:
def random_permute_generator(iterable, n=10):
"""Yield a random permuation of an iterable n times."""
for _ in range(n):
yield mit.random_permutation(iterable)
list(random_permute_generator(range(10), n=20))
# [(2, 7, 9, 6, 5, 0, 1, 3, 4, 8),
# (7, 3, 8, 1, 2, 6, 4, 5, 9, 0),
# (2, 3, 1, 8, 7, 4, 9, 0, 6, 5),
# (0, 5, 6, 8, 2, 3, 1, 9, 4, 7),
# (0, 8, 1, 9, 4, 5, 7, 2, 3, 6),
# (7, 2, 5, 8, 3, 4, 1, 0, 9, 6),
# (9, 1, 4, 5, 8, 0, 6, 2, 7, 3),
# (3, 6, 0, 2, 9, 7, 1, 4, 5, 8),
# (8, 4, 0, 2, 7, 5, 6, 1, 9, 3),
# (4, 9, 0, 5, 7, 1, 8, 3, 6, 2)
# ...]
Pour votre problème spécifique, remplacez le nombre itératif et le nombre d'appels n
par les valeurs appropriées, par exemple. random_permute_generator(iterable, n=5000)
.
Voir aussi more_itertools
docs pour plus d’informations sur cet outil.
Détails
Pour les intéressés, voici la recette actuelle.
À partir des recettes d'itertools :
def random_permutation(iterable, r=None):
"Random selection from itertools.permutations(iterable, r)"
pool = Tuple(iterable)
r = len(pool) if r is None else r
return Tuple(random.sample(pool, r))