【问题标题】:Collections.shuffle only working onceCollections.shuffle 只工作一次
【发布时间】:2013-03-30 12:04:19
【问题描述】:

我检查了以前的答案,但它对我不起作用。

我有以下代码

public static void createPopulation(ArrayList<City> city)
{
    for (int i = 0; i<gen.getSize(); i++)   {   
        ArrayList<City> copy = new ArrayList<City> (city); //added from previous question
        Collections.shuffle(copy, new Random(seed));
        gen.add(copy);
    }
}

它会随机播放一次,无论是否带有注释行,但不会再次随机播放。这是一个 GP 算法(嗯,它的开始),我必须在其中洗牌人口的成员。

【问题讨论】:

  • 什么是seed?当您从相同的种子值创建一个新的Random 时,它每次都会为您提供相同的“随机”数字序列。

标签: java collections random shuffle


【解决方案1】:

那是因为您重新创建了 Random 对象。

这样做:

Random r = new Random(seed);
for (int i = 0; i<gen.getSize(); i++)   {   
    ArrayList<City> copy = new ArrayList<City> (city); //added from previous question
    Collections.shuffle(copy, r);
    gen.add(copy);
}

来自the javadoc

如果 Random 的两个实例使用相同的种子创建,并且 为每个方法调用相同的序列,它们将生成和 返回相同的数字序列。

Random 的一个实例是一个生成器,每次调用随机函数时,它的状态都会改变。在这里,您不想将此状态重置为基于初始种子的状态,因为这会导致相同的返回数字序列。这就是为什么您不想为每次改组重新创建一个新实例的原因。

【讨论】:

  • 您是说他们应该重用Random 对象还是问题在于他们(基本上)这样做了?我觉得我一定很愚蠢并且遗漏了一些东西,但是在我看来,您的代码会导致与问题中的代码完全相同。
  • 我进行了编辑,因为它措辞不当。 shuffle 调用随机函数,如果您为每次 shuffle 重新创建相同的 Random 对象,那么您每次都执行完全相同的操作序列。如果您只初始化对象一次,则操作顺序不会重新开始,结果会有所不同。需要理解的重要一点是 Random 实例(生成器)有一个状态,并且在它上面调用任何随机函数都会改变这个状态。
  • 现在更有意义了。谢谢!