2015-11-27 40 views
7

Python'a yeni geldim ve rastgele listeler oluşturma konusunda bazı problemlerim var.Python rasgele listesi

random.sample(range(x, x), y) kullanıyorum.

ben 1-4 benzersiz sayılarla 4 listeleri, almak istiyorum, bu yüzden bu

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) 

Yani örneğin

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

için olsun kullanıyoruz Nasıl yapabilir o sütun da benzersizdir?

+0

evet, ama sadece 1-4 arası rakamlar :) – PythonUserNew

+0

Rastgele bir Latin kare oluşturmaya mı çalışıyorsunuz? –

+0

@ John Coleman, evet, bir latin kare – PythonUserNew

cevap

1

Muhtemelen en basit yolu, geçerli bir matris oluşturmak ve sonra satırları karıştırmak ve sonra sütunları karıştırmak için geçerli:

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 

Kullanımı:

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

Bu oluşturmak mümkün olmalıdır eşit olasılıklı herhangi bir geçerli matris. Bazı okumalar yaptıktan sonra, bunun neden olduğunu tam olarak anlayamasam da, bunun hala bir önyargıya sahip olduğu görünüyor.

1

Tüm elemanların bir listesini oluşturun ve satırı dolduracağınız gibi, kullanılmış elemanı çıkarın.

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

Net bir matematiksel teori bulunmadığı için, bir tür vur-kaç bir yaklaşımdan başka bir şeye güvenmem.

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 

Tipik çıkış:

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

üretmek gerekiyor çok teşekkür ederim, deneyeceğim ve deneyeceğim: D – PythonUserNew

+0

Bu yöntem tamamen önyargısızdır, ancak bu N gibi __very__ verimsiz bir yöntemdir. büyür. Son sırada N var! permütasyonlar, ancak sadece 1 mümkündür. Bu, çalışma zamanını en azından O (N!) Konumuna getirir. Python rasgele sayı üretecinin dahili olarak içerdiği bit sayısına bağlı olarak, büyük N. – orlp

2

sonra tamamen rastgele:

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

için sonlanmayabilir. Bunun için muhtemelen en iyi cevap. Kısa özlü ve çalışır. Ve burada bunu yapmak için aşırı karmaşık fonksiyonlar yapıyordum. Nice +1 –

+0

Bu, farklı şekilde kodlanmış olanlar hariç benim yanıtımla aynıdır. – orlp

0

I 1 ile rasgele latin kare oluşturmak olacaktır) başlangıç ​​Özellikle, yaklaşımları geriye ince bir yanlılığı yaratabilir tek rastgele bir permütasyonla, 2) satırları rotasyonlarla doldurun 3) satırları karıştırın 4) kareyi dönüştürün 5) satırları tekrar karıştırın:

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)