为什么要在 shuffle 方法中添加一个随机变量?

Why would you add a random variable to the shuffle method?

我不明白在 shuffle 方法中使用额外的随机数。从我到目前为止看到的示例来看,它没有任何好处,或者有什么好处? 它说它指定了随机性的来源,但是,随机播放方法本身不是随机的吗?那么为什么我要进一步指定它呢?

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);

//What is the difference?
Collection.shuffle(list);
Collection.shuffle(list, new Random(2));

随机参数指定随机源

如果您使用相同的种子创建两个随机对象,则使用这些对象随机排列 2 个列表,如下所示:

Random R1 = new Random(1);
Random R2 = new Random(1); //Same seeds

Collections.shuffle(List1, R1);
Collections.shuffle(List2, R2);

然后两个列表将按相同的顺序进行洗牌。如果列表相同,则结果也将相同。

如果您出于某种原因需要随机生成的东西是可复制的,它会很有用。例如在 Minecraft 中,世界是随机生成的 - 但玩家可以共享生成世界的种子,以便其他人可以生成完全相同的世界。

您可能希望提供默认来源以外的随机来源的主要原因有两个:

  1. 再现性;和
  2. 使用更好的 Pseudo-Random 数字生成器 (PRNG)。

#1 — 值序列 shuffle() 用于执行随机播放,因此结果的顺序取决于调用随机播放方法时生成器的状态。如果您克隆您的列表,并在原始列表上调用 shuffle(),然后使用默认 PRNG 在其克隆上调用,您将得到两个不同的结果。同样,如果您或其他人多次 运行 执行您的程序,每次 运行 都会导致不同的洗牌,因为 PRNG 种子会不同。结果的可重复性对于调试以及允许同事验证您的研究结果至关重要。为了实现可重复性,传递 shuffle() 具有固定种子的 Random 对象。

#2 — Java 对 Random 的实现是 48 位 Linear Congruential Generator. Not bad, but not great either. If you wish to use a third-party generator such as WELL or variations on xoroshiro,您可以通过使用所需的替代 PRNG 调用 shuffle() 来实现。