2015-11-27 11 views
7

Ich bin neu in Python, und habe einige Probleme mit dem Erstellen von zufälligen Listen.Python zufällige Liste

Ich verwende random.sample(range(x, x), y).

Ich möchte vier Listen mit eindeutigen Nummern bekommen, von 1 bis 4, so habe ich das schon mit

a = random.sample(range(1, 5), 4) 
b = random.sample(range(1, 5), 4) 
c = random.sample(range(1, 5), 4) 
d = random.sample(range(1, 5), 4) 

Also ich zum Beispiel bekommen

a = 1, 3, 2, 4 
b = 1, 4, 3, 2 
c = 2, 3, 1, 4 
d = 4, 2, 3, 1 

Wie kann ich es machen, dass die Spalte ist auch einzigartig?

+0

ja, aber nur die Zahlen 1 - 4 :) – PythonUserNew

+0

Willst du ein zufälliges lateinisches Quadrat erzeugen? –

+0

@ John Coleman, ja, ich muss ein lateinisches Quadrat generieren – PythonUserNew

Antwort

1

Wahrscheinlich ist der einfachste Weg, eine gültige Matrix zu erstellen, und dann die Zeilen mischen und dann die Spalten Shuffle:

import random 

def random_square(U): 
    U = list(U) 
    rows = [U[i:] + U[:i] for i in range(len(U))] 
    random.shuffle(rows) 
    rows_t = [list(i) for i in zip(*rows)] 
    random.shuffle(rows_t) 
    return rows_t 

Verbrauch:

>>> random_square(range(1, 1+4)) 
[[2, 3, 4, 1], [4, 1, 2, 3], [3, 4, 1, 2], [1, 2, 3, 4]] 

Dies sollte schaffen sein können jede gültige Matrix mit gleicher Wahrscheinlichkeit. Nach etwas lesen scheint es, dass dies immer noch Voreingenommenheit hat, obwohl ich noch nicht vollständig verstehe warum.

1

Erstellen Sie eine Liste aller Elemente, und wie das Füllen der Zeile, entfernen Sie das verwendete Element.

import random 

def fill_line(length): 
    my_list = list(range(length)) 

    to_return = [] 

    for i in range(length): 
     x = random.choice(my_list) 

     to_return.append(x) 
     my_list.remove(x) 

    return to_return 

x = [fill_line(4) 
    for i in range(4)] 

print(x) 
3

Ohne eine klare mathematische Theorie, misstraue ich alles andere als ein etwas Hit-and-Miss-Ansatz. Insbesondere können Ansätze Rückzieher eine subtile Bias vorstellen:

from random import shuffle 

def isLatin(square): 
    #assumes that square is an nxn list 
    #where each row is a permutation of 1..n 
    n = len(square[0]) 
    return all(len(set(col)) == n for col in zip(*square)) 

def randSquare(n): 
    row = [i for i in range(1,1+n)] 
    square = [] 
    for i in range(n): 
     shuffle(row) 
     square.append(row[:]) 
    return square 

def randLatin(n): 
    #uses a hit and miss approach 
    while True: 
     square = randSquare(n) 
     if isLatin(square): return square 

typische Ausgabe:

>>> s = randLatin(4) 
>>> for r in s: print(r) 

[4, 1, 3, 2] 
[2, 3, 4, 1] 
[1, 4, 2, 3] 
[3, 2, 1, 4] 
+0

Vielen Dank Jungs, ich werde experimentieren und es ausprobieren: D – PythonUserNew

+0

Diese Methode ist völlig ohne Verzerrung, aber das ist eine __sehr__ ineffiziente Methode jedoch als N wächst. Für die letzte Reihe gibt es N! Permutationen, aber nur 1 ist machbar. Dies setzt die Laufzeit mindestens auf O (N!). Abhängig von der Anzahl der Bits, die der Python-Zufallszahlengenerator intern hat, endet er möglicherweise niemals für großes N. – orlp

2

total gelegentlichem dann:

def gen_matrix(): 
    first_row = random.sample(range(1, 5), 4) 
    tmp = first_row + first_row 
    rows = [] 
    for i in range(4): 
     rows.append(tmp[i:i+4]) 
    return random.sample(rows, 4) 
+0

Wahrscheinlich die beste Antwort dafür. Kurz und prägnant und funktioniert. Und hier machte ich übermäßig komplexe Funktionen, um dies zu tun. Nice +1 –

+0

Das ist effektiv identisch mit meiner Antwort, außer anders codiert. – orlp

0

ich eine zufällige lateinische Quadrat von 1 bauen würde) Start mit einer einzigen zufälligen Permutation, 2) füllen Sie die Reihen mit Rotationen 3) mischen Sie die Reihen 4) transponieren Sie das Quadrat 5) mischen Sie die Reihen wieder:

from collections import deque 
from random import shuffle 

def random_latin_square(elements): 
    elements = list(elements) 
    shuffle(elements) 
    square = [] 
    for i in range(len(elements)): 
     square.append(list(elements)) 
     elements = elements[1:] + [elements[0]] 
    shuffle(square) 
    square[:] = zip(*square) 
    shuffle(square) 
    return square 

if __name__ == '__main__': 
    from pprint import pprint 
    square = random_latin_square('ABCD') 
    pprint(square) 
Verwandte Themen