我有一个洗牌问题。有很多关于完全改组数值的页面和讨论,比如一叠牌。
我需要的是一个shuffle,它将数组元素从最初的N个位置均匀地移位。
即如果N为2,则元素I最多将被拖曳到从I-2到I + 2的位置(在数组的范围内)。
事实证明,使用一些简单的解决方案会导致对元素移动的方向性偏差,或者通过不均匀的量,这是非常棘手的。
答案 0 :(得分:2)
你是对的,这很棘手!首先,我们需要制定更多规则,以确保我们不会创造人为的非随机结果:
现在我们可以解决问题了。
i + [-N, N]
范围内的随机值数组,其中i
是数组中的当前索引。规范化数组范围之外的值(例如-1
应该变为length-1
而length
应变为0
。)[3, 1, 1, 0]
索引2
中可用),从该集合中选择一个随机值,并将其中一个数组值设置为选定的结果。这避免了在解决冲突之前需要循环,但是代码更复杂,并且在集合为空的情况下可能会遇到风险。我不确定如何最好地实施#2,我建议您对其进行基准测试。如果您不想花时间进行基准测试,我会选择第一个选项。其他的是可能更快的优化,但实际上可能会变慢。
此解决方案在理论上具有无限运行时间,但在实践中应该合理地快速终止。再次,在使用它之前进行基准测试并对其进行测试。
答案 1 :(得分:0)
我已经提出了一个可能的解决方案,但是如何“天真地”'我不确定。特别是在边缘处,尤其是远边缘。
创建一个标志数组(布尔值)N long(表示已交换的元素)
For At每个索引检查它是否已经被交换(根据flags数组中的第一个元素),如果是的话,继续下一个(见下文)
旋转flags数组,删除第一个元素(表示这个 元素),并添加一个新的' not swapped'元素结束。 ASIDE:这个 也许使用模数阵列查找,以避免实际 移动数组内容,特别是对于大N
...循环
使用选定的未切换元素交换当前元素,将所选元素标记为flags数组中的交换。循环到下一个元素