web-dev-qa-db-ja.com

Pythonで配列の順列を生成する方法は?

27要素の配列があり、配列のすべての順列を生成する必要はありません(27!)ランダムに選択された5000の順列が必要です。任意のヒントが役立ちます...

27
user257522

1つの順列を生成するには、 random.shuffle を使用して、結果のコピーを保存します。この操作をループで繰り返し、毎回重複がないか確認します(ただし、おそらく重複はありません)。結果セットに5000項目が含まれたら、停止します。

コメントのポイントに対処するために、Pythonの ランダムモジュールMersenne Twister に基づいており、2**19937-1の周期を持っています。これは27!なので、あなたの使用に適しているはずです。

36
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大きな数字が大好きです。 :)

そして

10888869450418352160768000001はプライムです!!

編集:

#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

警告:RNGが悪い場合、これは停止しません!

11
Pratik Deoghare

itertools.permutations 。これはジェネレーターであるため、順列のリスト全体が作成されるわけではありません。 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
_

使用法:perm_given_index(['a','b','c'], 3)

これは、jの値がそれに一致するため、置換にレーマーコードを使用します。

3
Dan D.

Itertools.permutations()関数が必要になる場合があります。お奨めは、そのitertoolsモジュールが大好きです!

注:2.6の新機能

1
ironfroggy

_random_permutation_ itertools Recipes の実装を試すことができます。便宜上、このレシピを実装するサードパーティのライブラリ _more_itertools_ を使用します。

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

関数の呼び出しごとにランダムな順列が作成されます。 n呼び出しに対してこれらの結果を生成するジェネレーターを作成できます。このジェネレーターを実装し、簡単な例でランダムな結果を示します。

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

特定の問題については、反復可能な呼び出しの数nを適切な値に置き換えます。 random_permute_generator(iterable, n=5000)

このツールの詳細については、 _more_itertools_ docs も参照してください。


詳細

興味のある方のために、こちらが実際のレシピです。

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