2013-04-08 138 views
3

我查了以前的答案,但它不适合我。Collections.shuffle只能工作一次

我有以下代码

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算法(好吧,它的开始),我必须洗牌的人群。

+0

什么是'种子'?当你从相同的种子值创建一个新的“Random”时,它会每次给你相同的“随机”数字序列。 – 2013-04-08 12:06:37

回答

10

这是因为您重新创建了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的一个实例是一个发生器,每当你调用一个随机函数时它的状态就会改变。在这里你不想重置这个状态到基于种子的初始状态,因为这会导致返回数字的相同序列。这就是为什么你不想为每个洗牌重新创建一个新的实例。

+1

你是说他们应该重用'Random'对象,或者问题是他们(基本上)是这样做的?我觉得我一定很愚蠢并且错过了一些东西,但是你的代码在我看来会像导致与问题中的代码完全一样。 – 2013-04-08 12:12:31

+1

我编辑,因为它措辞不佳。 'shuffle'调用随机函数,如果为每个随机重新创建相同的Random对象,则每次都执行完全相同的操作序列。如果仅初始化对象一次,则操作顺序不会重新启动,结果也会不同。要理解的重要一点是Random实例(generator)具有一个状态,并调用其上的任意随机函数来改变此状态。 – 2013-04-08 12:20:51

+0

这使得现在更有意义。谢谢! – 2013-04-08 12:24:07