web-dev-qa-db-fra.com

comment générer des permutations de tableau en python?

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 ...

25
user257522

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.

35
Mark Byers
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!

11
Pratik Deoghare

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.

6
Cat Plus Plus
# 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.

3
Dan D.

Vous voudrez peut-être la fonction itertools.permutations (). Je dois aimer ce module itertools!

NOTE: Nouveau dans 2.6

1
ironfroggy

Vous pouvez essayer d'implémenter les recettes random_permutationitertools . 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))
0
pylang