python 具有更多随机性的排列
python permutations with more randomization
我正在尝试从索引列表生成排列,目前,我正在使用 itertools.permutation
。没关系,除了我需要索引的真正随机性,因为 我将无法 select 所有排列 ,但总集的一个非常短的子集(初始一个)用于模拟。
对于itertools.permutation
:
排列元组根据输入可迭代的顺序按字典顺序发出。因此,如果输入可迭代对象已排序,组合元组将按排序顺序生成。
import itertools
for ind, idxs in enumerate(itertools.permutations(range(5))):
print(ind)
print(idxs)
print('--------')
0
(0, 1, 2, 3, 4)
--------
1
(0, 1, 2, 4, 3)
--------
2
(0, 1, 3, 2, 4)
--------
3
(0, 1, 3, 4, 2)
--------
4
(0, 1, 4, 2, 3)
--------
5
(0, 1, 4, 3, 2)
--------
6
(0, 2, 1, 3, 4)
--------
7
(0, 2, 1, 4, 3)
--------
8
(0, 2, 3, 1, 4)
--------
9
(0, 2, 3, 4, 1)
--------
10
(0, 2, 4, 1, 3)
--------
11
(0, 2, 4, 3, 1)
--------
12
(0, 3, 1, 2, 4)
--------
13
(0, 3, 1, 4, 2)
--------
我想到的一个解决方案是每次都打乱列表以获得随机顺序,但这使得排列的想法过时了,这是不希望的,因为有可能会生成相同的样本不止一次。排列应该迭代生成,所以我不能只做 list(itertools.permutation..)
因为这会产生一个非常不必要的长列表。
使用random.sample
:
permutations = list(itertools.permutations(range(5)))
permutation = random.sample(permutations, k=4)
# run 1
>>> random.sample(permutations, k=4)
[(0, 4, 1, 2, 3), (4, 0, 1, 3, 2), (3, 2, 0, 4, 1), (1, 2, 3, 4, 0)]
# run 2
>>> random.sample(permutations, k=4)
[(2, 1, 4, 0, 3), (0, 3, 4, 1, 2), (3, 1, 4, 0, 2), (0, 3, 4, 2, 1)]
# run 3
>>> random.sample(permutations, k=4)
[(3, 4, 1, 0, 2), (3, 0, 1, 2, 4), (0, 4, 1, 2, 3), (3, 4, 2, 0, 1)]
# and so on
一种方法是在生成排列后 and/or 之前洗牌。
供参考:
import itertools
import random
a = list(range(3))
print("original =",a)
random.shuffle(a)
print("shuffled =",a)
permutations = list(itertools.permutations(a))
print("permutations of shuffled array =",permutations)
random.shuffle(permutations)
print("shuffled permutations of shuffled array =",permutations)
original = [0, 1, 2]
shuffled = [1, 0, 2]
permutations of shuffled array = [(1, 0, 2), (1, 2, 0), (0, 1, 2), (0, 2, 1), (2, 1, 0), (2, 0, 1)]
shuffled permutations of shuffled array = [(0, 1, 2), (2, 0, 1), (2, 1, 0), (1, 0, 2), (1, 2, 0), (0, 2, 1)]
生成随机排列:如果您只使用其中的少数 k 个,您获得两次相同排列的机会是 k/n!。
我正在尝试从索引列表生成排列,目前,我正在使用 itertools.permutation
。没关系,除了我需要索引的真正随机性,因为 我将无法 select 所有排列 ,但总集的一个非常短的子集(初始一个)用于模拟。
对于itertools.permutation
:
排列元组根据输入可迭代的顺序按字典顺序发出。因此,如果输入可迭代对象已排序,组合元组将按排序顺序生成。
import itertools
for ind, idxs in enumerate(itertools.permutations(range(5))):
print(ind)
print(idxs)
print('--------')
0
(0, 1, 2, 3, 4)
--------
1
(0, 1, 2, 4, 3)
--------
2
(0, 1, 3, 2, 4)
--------
3
(0, 1, 3, 4, 2)
--------
4
(0, 1, 4, 2, 3)
--------
5
(0, 1, 4, 3, 2)
--------
6
(0, 2, 1, 3, 4)
--------
7
(0, 2, 1, 4, 3)
--------
8
(0, 2, 3, 1, 4)
--------
9
(0, 2, 3, 4, 1)
--------
10
(0, 2, 4, 1, 3)
--------
11
(0, 2, 4, 3, 1)
--------
12
(0, 3, 1, 2, 4)
--------
13
(0, 3, 1, 4, 2)
--------
我想到的一个解决方案是每次都打乱列表以获得随机顺序,但这使得排列的想法过时了,这是不希望的,因为有可能会生成相同的样本不止一次。排列应该迭代生成,所以我不能只做 list(itertools.permutation..)
因为这会产生一个非常不必要的长列表。
使用random.sample
:
permutations = list(itertools.permutations(range(5)))
permutation = random.sample(permutations, k=4)
# run 1
>>> random.sample(permutations, k=4)
[(0, 4, 1, 2, 3), (4, 0, 1, 3, 2), (3, 2, 0, 4, 1), (1, 2, 3, 4, 0)]
# run 2
>>> random.sample(permutations, k=4)
[(2, 1, 4, 0, 3), (0, 3, 4, 1, 2), (3, 1, 4, 0, 2), (0, 3, 4, 2, 1)]
# run 3
>>> random.sample(permutations, k=4)
[(3, 4, 1, 0, 2), (3, 0, 1, 2, 4), (0, 4, 1, 2, 3), (3, 4, 2, 0, 1)]
# and so on
一种方法是在生成排列后 and/or 之前洗牌。
供参考:
import itertools
import random
a = list(range(3))
print("original =",a)
random.shuffle(a)
print("shuffled =",a)
permutations = list(itertools.permutations(a))
print("permutations of shuffled array =",permutations)
random.shuffle(permutations)
print("shuffled permutations of shuffled array =",permutations)
original = [0, 1, 2] shuffled = [1, 0, 2] permutations of shuffled array = [(1, 0, 2), (1, 2, 0), (0, 1, 2), (0, 2, 1), (2, 1, 0), (2, 0, 1)] shuffled permutations of shuffled array = [(0, 1, 2), (2, 0, 1), (2, 1, 0), (1, 0, 2), (1, 2, 0), (0, 2, 1)]
生成随机排列:如果您只使用其中的少数 k 个,您获得两次相同排列的机会是 k/n!。