随机播放一个阵列使得没有元素移动超过K个位置

时间:2018-01-17 18:36:59

标签: arrays algorithm random shuffle

我有一个数组,我想将数组洗牌,这样任何元素都不会从数组中的初始位置移动超过K个位置。例如,如果K为2,则原始数组为:

[1,2,3,4,5,6,7,8]

这是一种有效的排列:

[1,3,2,5,4,8,6,7]

但这不是:

[1,2,5,4,6,8,3,7]

因为3移动了4个位置。

有没有办法做到这一点,这是一个完全随机的混乱(换句话说,满足这个标准的所有排列同样可能?)

1 个答案:

答案 0 :(得分:0)

以下是执行此操作的Python代码,但所有排列都同样可能的证据留给读者练习(意思是,我不知道如何证明它,我不确定概率是真的相等:))。

这个想法是这样的:

  • 对于结果数组中的每个位置,我们从中选择一个元素 原始数组不超过所需的距离和 以前没有选过的。
  • 如果在某个位置我们发现我们有一个未选择的原始元素 数组恰好是当前的最大距离 我们选择那个元素(最后的机会选择)。
import random

initial_array = [x for x in range(1, 10)]
max_distance = 3
element_taken = [(i < max_distance) or i > (len(initial_array) + max_distance - 1) for i in range(len(initial_array) + max_distance * 2)]

result = [0] * len(initial_array)

for i in range(len(initial_array)):
    print ("Position", i)
    print ("Original", initial_array)
    print ("  Result", result)
    print ("   Taken", element_taken)
    if not element_taken[i]:
        element_taken[i] = True
        result[i] = initial_array[i - max_distance]
        print ("Had to use last-chance move from %d to %d" % (i - max_distance, i))
        continue
    possible_positions = [position for position in range(i - max_distance, i + max_distance + 1) if not element_taken[max_distance + position]]
    print ("Possible positions", possible_positions)
    position = random.choice(possible_positions)
    print ("Moving %d to %d" % (position, i))
    result[i] = initial_array[position]
    element_taken[max_distance + position] = True

print ()
print ("   Final", result)