У меня есть массив из 27 элементов, и я не хочу генерировать все перестановки массива (27!) мне нужно 5000 случайно выбранных перестановок, любой совет будет полезен...
Как создать перестановки массива в python?
Ответ 1
Чтобы сгенерировать одну перестановку, используйте random.shuffle
и сохраните копию результата. Повторите эту операцию в цикле и каждый раз проверяйте наличие дубликатов (вероятно, их не будет). Когда у вас есть 5000 предметов в вашем результирующем наборе, остановитесь.
Чтобы указать точку в комментарии, Python случайный модуль основан на Mersenne Twister и имеет период 2**19937-1
, который значительно больше, чем 27!
, поэтому он должен быть подходящим для вашего использования.
Ответ 2
import random
perm_list = []
for i in range(5000):
temp = range(27)
random.shuffle(temp)
perm_list.append(temp)
print(perm_list)
10888869450418352160768000000
Я люблю большие цифры!:)
и
10888869450418352160768000001
является 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
ПРЕДУПРЕЖДЕНИЕ: это никогда не остановится, если RNG плох!
Ответ 3
itertools.permutations
. Это генератор, поэтому он не будет создавать весь список перестановок. Вы можете пропустить случайным образом, пока не получите 5000.
Ответ 4
# 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)
Это использует код Lehmer для перестановки, так как значения j
соответствуют этому.
Ответ 5
Вам может понадобиться функция itertools.permutations(). Должен любить модуль itertools!
ПРИМЕЧАНИЕ: Новое в версии 2.6
Ответ 6
Вы можете попробовать выполнить random_permutation
рецепты itertools. Для удобства я использую стороннюю библиотеку, 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 для получения дополнительной информации об этом инструменте.
Подробнее
Для желающих, вот настоящий рецепт.
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))