Python 快速随机配对置换
我需要为整数(索引)的有序数组生成一个随机配对排列。例如,对于Python 快速随机配对置换,python,arrays,algorithm,random,permutation,Python,Arrays,Algorithm,Random,Permutation,我需要为整数(索引)的有序数组生成一个随机配对排列。例如,对于N=10,输入数组如下所示: [0 1 2 3 4 5 6 7 8 9] 有效的随机配对排列为: [7 8 6 5 9 3 2 0 1 4] 请注意,索引是随机配对的,即:如果元素0(输入数组)与7(排列数组中的0th位置)配对,则元素7(输入数组)与0(排列数组中的7th位置)配对,以此类推。 输入数组中的任何元素都不能与其自身配对,即这不是有效的排列: [7 1 6 5 9 3 2 0 8 4] 因为元素1和8处于其“索引”
N=10
,输入数组如下所示:
[0 1 2 3 4 5 6 7 8 9]
有效的随机配对排列为:
[7 8 6 5 9 3 2 0 1 4]
请注意,索引是随机配对的,即:如果元素0
(输入数组)与7
(排列数组中的0
th位置)配对,则元素7
(输入数组)与0
(排列数组中的7
th位置)配对,以此类推。
输入数组中的任何元素都不能与其自身配对,即这不是有效的排列:
[7 1 6 5 9 3 2 0 8 4]
因为元素1
和8
处于其“索引”位置。这与SO中已多次涉及的主题有关:
N
值,它会变得非常慢。我需要对N~1500
执行数千次此操作,这意味着此方法没有用处
我肯定有更聪明的方法来做这件事
N = 10
idxs = np.arange(N)
# Generate a shuffled array
input_idxs = idxs.copy()
np.random.shuffle(input_idxs)
# Empty array to store the final randomly paired indexes
shuffled_idxs = np.zeros(N, dtype=int)
used_idxs = []
for i in idxs:
if i not in used_idxs:
for j in input_idxs:
if j not in used_idxs:
if j != i:
shuffled_idxs[i] = j
shuffled_idxs[j] = i
used_idxs.append(i)
used_idxs.append(j)
break
互换配对意味着N始终是偶数。如果是这种情况,那么您可以抽取一半索引的样本,并将它们与剩余索引的无序列表配对:
import random
def randomPairs(N):
result = [None] * N
A = random.sample(range(N),N//2)
B = random.sample(list(set(range(N))-set(A)),N//2)
for a,b in zip(A,B):
result[a] = b
result[b] = a
return result
for _ in range(10):
print(randomPairs(6))
[4, 3, 5, 1, 0, 2]
[5, 4, 3, 2, 1, 0]
[5, 3, 4, 1, 2, 0]
[2, 3, 0, 1, 5, 4]
[3, 2, 1, 0, 5, 4]
[2, 3, 0, 1, 5, 4]
[4, 2, 1, 5, 0, 3]
[3, 4, 5, 0, 1, 2]
[2, 3, 0, 1, 5, 4]
[1, 0, 3, 2, 5, 4]
性能
# 1000 shuffles of 1500 elements in pairs
def test1():
for _ in range(1000):
randomPairs(1500)
from timeit import timeit
count = 1
t = timeit(test1,number=count)
print(t) # 1.12 seconds
[编辑]一个稍微快一点的解决方案是洗牌所有索引,并在洗牌列表中每隔一个位置与下一个位置配对:
import random
def randomPairs(N):
result = [None] * N
A = random.sample(range(N),N)
for a,b in zip(A[::2],A[1::2]):
result[a] = b
result[b] = a
return result
为了确保我理解正确:您的目标是随机交换列表中的元素,要求每个数字只交换一次,对吗?我想您可以这样想。主要的一点是,随机交换必须成对进行。