2015-11-27 6 views
7

私はPythonを初めて使い、ランダムリストの作成にいくつか問題があります。Pythonランダムリスト

私はrandom.sample(range(x, x), y)を使用しています。

だから私は、例えば

私がいること、それを作ることができますどのように
a = 1, 3, 2, 4 
b = 1, 4, 3, 2 
c = 2, 3, 1, 4 
d = 4, 2, 3, 1 

を取得し、私は1-4から、ユニークな数字で4つのリストを取得したいので、私はこの

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) 

を使用しています列もユニークですか?

+0

はい、しかし、数字だけの1- 4 :) – PythonUserNew

+0

あなたはランダムなラテン方陣を生成しようとしていますか? D –

+0

ジョン・コールマン、@、はい、私は、私はつもり実験だと、それを試してみるそんなにみんなに感謝ラテン平方 – PythonUserNew

答えて

1

は、おそらく最も簡単な方法は、有効な行列を作成し、行をシャッフルして、列をシャッフルすることです:

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 

使用法:

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

これは、作成することができるはず等確率の任意の有効な行列。 いくつかの読書をした後、私はまだなぜそれが完全に理解されていませんが、まだ偏見があるようです。

1

すべての要素のリストを作成し、ラインを充填するように、使用される要素を削除します。

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

明らかな数学的理論がない場合、私は幾分ヒットアンドミスのアプローチ以外の何かを信じていません。

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 

典型的な出力:

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

を生成する必要があります成長する。最後の行にはN!順列は可能ですが、1つしか実行できません。これは少なくともランタイムをO(N!)に置きます。 Python乱数ジェネレータが内部的に持っているビットの数によっては、大きなNのために決して終了しないかもしれません。 – PythonUserNew

+0

は、この方法は、バイアスなしで完全であるが、これはしかし、Nとして__very__非効率的な方法である: – orlp

2

その後、完全にランダム:

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

これはおそらく最良の答えです。短い簡潔さと作品。そして、ここで私はこれを行うために過度に複雑な機能を行っていました。ニース+1 –

+0

これは私の答えと事実上同じですが、コードは異なっています。 – orlp

0

は私が1によるランダムラテン広場を建設する)開始特に、アプローチをバックトラッキングすることは微妙なバイアスを導入することができます単一のランダムな順列と、2))4)正方形5転置行をシャッフル)回転3と行を移入再度行をシャッフル:

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) 
関連する問題