我想以最小的偏差反复产生快速的随机洗牌。
众所周知,只要底层随机数生成器 (RNG) 是无偏的, Fisher-Yates 洗牌就是无偏的。
To shuffle an array a of n elements:
for i from n − 1 downto 1 do
j ← random integer with 0 ≤ j ≤ i
exchange a[j] and a[i]
但是,如果 RNG 有偏差(但速度很快)怎么办?
假设我想生成一个包含 25 个元素的数组的许多随机排列。如果我使用带有偏差 RNG 的 Fisher-Yates 算法,那么我的排列将会有偏差,但我相信这假设 25 元素数组在每次应用 shuffle 算法之前从相同状态开始。例如,一个问题是,如果 RNG 只有 2^32 ~ 10^9 的周期,我们不能产生 25 个元素的所有可能排列,因为这是 25!~ 10^25 排列。
我的一般问题是,如果我在开始 Fisher-Yates 洗牌的每个新应用之前让洗牌的元素洗牌,这会减少偏差和/或允许算法产生每个排列吗?
我的猜测是它通常会产生更好的结果,但似乎如果被反复洗牌的数组有许多与底层 RNG 相关的元素,那么排列实际上可能比预期的更频繁地重复。
有谁知道解决这个问题的任何研究?
作为一个子问题,如果我只想重复排列数组中 25 个元素中的 5 个,那么我使用 Fisher-Yates 算法选择 5 个元素并在进行完全洗牌之前停止怎么办?(我使用被交换的数组末尾的 5 个元素。)然后我重新开始使用之前部分洗牌的 25 元素数组来选择另一个 5 的排列。同样,这似乎比从如果底层 RNG 有偏差,则为原始 25 元素数组。对此有什么想法吗?
我认为测试部分洗牌情况会更容易,因为 25 个元素中的 5 个只有 6,375,600 种可能的排列,那么是否有任何简单的测试可用于检查偏差?