2010-01-23 27 views
24

i eine Reihe von 27 Elementen haben, und ich will nicht alle Permutationen von Array erzeugen (27!) ich brauche 5000 zufällig choosed Permutationen, wird jede Spitze nützlich sein ...wie Permutationen von Array in Python generieren?

+5

Es könnte sich lohnen zu erwähnen, dass '' 27 ist 10888869450418352160768000000. –

Antwort

35

Um eine Permutation zu generieren, verwenden Sie random.shuffle und speichern Sie eine Kopie des Ergebnisses. Wiederholen Sie diesen Vorgang in einer Schleife und überprüfen Sie jedes Mal auf Duplikate (es wird wahrscheinlich auch keine geben). Sobald Sie 5000 Elemente in Ihrer Ergebnismenge haben, stoppen Sie.

den Punkt im Kommentar zu adressieren, random module Python auf dem Mersenne Twister basiert und hat eine Periode von 2**19937-1, die für die Nutzung erheblich größer als 27! ist so sollte es geeignet sein.

+4

+1, aber beachte, dass 'random.shuffle' eine schwerwiegende Schwäche hat: Der Zeitraum der meisten RNGs ist kleiner als die Gesamtzahl der Permutationen, wenn _n_ größer wird. Das bedeutet, dass fast alle möglichen Permutationen für ein großes _n_ niemals erzeugt werden können, so dass dies nicht wirklich zufällig ist. –

+3

In der Tat, John. Pythons Zufallsgenerator hat eine Periode von 2 ** 19937-1, also ist es wahrscheinlich gut genug. Ein weiterer Nitpick ist, dass für echte Zufallszahlen Sie eine echte zufällige Quelle (z. B. von radioaktivem Zerfall) benötigen, Python-Zufallsmodul bietet nur Pseudozufallszahlen. Aber im allgemeinen Gebrauch, wenn Leute "zufällig" sagen, was sie wirklich meinen, ist "Pseudozufall", und ich nehme an, dass das, was das Plakat hier bedeutet. –

+1

+1 Cool! Es ist ein großer Würfel mit einer Wahrscheinlichkeit von 1088886945041835216768000000, dass einer von ihnen auftaucht, ist 1/10888869450418352160768000000. Duplikate KEIN WEG !! –

6

itertools.permutations. Es ist ein Generator, also wird nicht die ganze Liste der Permutationen erstellt. Sie könnten zufällig überspringen, bis Sie 5000 haben.

+0

könnte lange dauern, diese Methode zu tun mit .... –

+2

Das ist nicht wirklich „zufällig“,! seit 'itertools' erstellt sie in einer definierten Reihenfolge, und es gibt eine endliche Anzahl von Permutationen. Was wäre besser, das folgende zu tun: (1) Bestimmen ** wie viele ** Permutationen gibt es (nennen Sie diese Zahl "N"), (2) dann generieren 5.000 verschiedene zufällige Indizes im Bereich "0. N- 1 ', (3) wählen Sie die Permutationen aus dem Generator itertools.permutations aus, die diesen Indizes entsprechen. –

+1

Ja, ich weiß, es ist nicht das Beste. Beim ersten Mal habe ich die Frage gelesen, dass ich diesen "zufällig ausgewählten" Teil irgendwie nicht bemerkt habe. Ich werde es nicht löschen, vielleicht jemand auf der Suche nach "wie man Permutationen von Array in Python generieren?" wird es nützlich finden. –

1

Sie möchten möglicherweise die itertools.permutations() -Funktion. Ich muss das Iertools-Modul lieben!

HINWEIS: Neue in 2,6

+2

Das wird zu langsam - er sagte, er habe 27 Elemente. –

11
import random 

perm_list = [] 

for i in range(5000): 
    temp = range(27) 
    random.shuffle(temp) 
    perm_list.append(temp) 

print(perm_list) 

10888869450418352160768000000 ich große Zahlen lieben! :)

UND

10888869450418352160768000001 ist PRIME !!

EDIT:

#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 

WARNUNG: Diese wird nicht immer aufhören, wenn RNG schlecht!

+0

Um auch nach Duplikaten zu suchen, wie es Mark vorschlägt, verwenden Sie 'perms = set()', 'dauer.add (tuple (temp))' und 'while len (perms) <5000' anstelle der for-Schleife. –

+0

@Beni Ich folgte deinem 'Tupel (Temp)' Vorschlag zuerst nicht, aber dann verstand ich, dass ich ein Dummkopf war !! Danke, Mann! –

2
# 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 

Verbrauch: perm_given_index(['a','b','c'], 3)

Dies verwendet die Lehmer-Code für die Permutation als die Werte von j dass entsprechen.

+0

Dies kann sehr nützlich sein, d. H. Für die Komprimierung, wenn Sie viele Permutationen speichern müssen, um stattdessen die Ganzzahldarstellung zu verwenden. Hat dich inspiriert, https://gist.github.com/lukmdo/7049748 zu schreiben – lukmdo

0

Sie können versuchen, die random_permutationitertools recipes zu implementieren. Der Einfachheit halber verwende ich eine Drittanbieter-Bibliothek, more_itertools, dass dieses Rezept für uns implementiert:

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) 

Eine zufällige Permutation für jeden Aufruf der Funktion erstellt wird. Wir können einen Generator erstellen, der diese Ergebnisse für n Aufrufe liefert. Wir werden diesen Generator implementieren und zeigen zufällige Ergebnisse mit einem gekürzten Beispiel:

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) 
# ...] 

Für Ihr spezielles Problem, ersetzen die iterable und Anzahl der Anrufe n mit den entsprechenden Werten, z.B. random_permute_generator(iterable, n=5000).

Siehe auch more_itertools docs für weitere Informationen zu diesem Tool.


Einzelheiten

Für Interessenten, hier ist das eigentliche Rezept.

Vom itertools recipes:

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)) 
Verwandte Themen