【发布时间】:2021-09-04 21:48:23
【问题描述】:
根据 wikipedia 以及 Java 标准库的实现,改组 https://en.wikipedia.org/wiki/Fisher–Yates_shuffle(Fisher Yates Shuffle)的工作方式如下:
算法 A:
-- To shuffle an array a of n elements (indices 0..n-1):
for i from n−1 downto 1 do
j ← random integer such that 0 ≤ j ≤ i
exchange a[j] and a[i]
或等效
算法 B:
-- To shuffle an array a of n elements (indices 0..n-1):
for i from 0 to n−2 do
j ← random integer such that i ≤ j < n
exchange a[i] and a[j]
我的问题是针对以下问题(算法 C):
算法 C:
-- To shuffle an array a of n elements (indices 0..n-1):
for i from 1 to n−1 do
j ← random integer such that 0 ≤ j ≤ i
exchange a[i] and a[j]
算法 A 和算法 B 完全相同。但是 Algo C 与 Algo A 和 Algo B 不同(实际上 Algo C 是 Algo A 反向执行)
算法 C 正确吗?我很迷茫。我使用列联表做了一些卡方检验,看起来这给出了明显正确的统一顺序。
我的问题是算法 C 是否正确?如果正确,为什么几乎看不到哪里?为什么 F-Y shuffle 到处都是同一个方向。
【问题讨论】:
-
好吧。有人跟我一样想。 possiblywrong.wordpress.com/2020/12/10/…我认为 Algo C 是正确的。
-
深奥:为什么要排除 A 和 C 中的索引零?还有
exchange a[i] and a[j]当然和exchange a[j] and a[i]是一样的。 -
嗯,当i = 0时,j肯定是0。不需要交换它们。
-
Algo C 肯定不是你想要的。对于 n=2,它将始终返回原始数组的反转,而不是原始数组。您确定这是您希望我们查看的代码吗?
-
@congyuwang:是的,但
i == j的任何时候都是如此,不是吗?
标签: algorithm computer-science probability shuffle pseudocode