编辑:问题解决了,确实来自子列表。谢谢!
我正在做一个关于遗传算法的项目。 但我有权利的错误,我真的不知道它发生在哪里,所以我需要你的帮助......
这是功能:
public synchronized void evolution(){
//TreeSet containing the 2 fathers and children
TreeChromosome t = new TreeChromosome();
Chromosome father1 = selection();
Chromosome father2;
do{father2= selection();}
while(father1==father2);
t.add(father1);
t.add(father2);
Chromosome child1 = OperatorGen.crossRight(father1, father2);
OperatorGen.swap(father1);
Chromosome child2 = OperatorGen.crossLeft(father1, father2);
OperatorGen.swap(child2);
t.add(fils1);
t.add(fils2);
// we add the best 2 in the population
Chromosome best1=t.pollFirst();
genotype.add(best1);
Chromosome best2=t.pollFirst();
genotype.add(best2);
//we remove the non selected chromosomes
for (Chromosome chromo : t) {
if (genotype.contains(chromo) && t.contains(chromo)){
genotype.remove(chromo);
}
}
genotype.updateRanks();
}
当我运行它时,它运行正常但是当我在循环中运行它时,我在OperatorGen.crossLeft上有例外... 这是这个函数的代码:
public static Chromosome crossLeft(Chromosome father1, Chromosome father2, int joint){
List<Ville> listFather1 = father1.getCities();
List<Ville> listFather2 = pere2.getCities();
//we copy the first cities of father1
List<Ville> listChild= listPere1.subList(0, joint);
City nextCity;
//we add the cities of father2
//block where the error appears, not always at the same line
for(int i=0;i<listFather2.size();i++){
nextCity=listFather2.get(i);
if(!listChild.contains(nextCity)){
listChild.add(nextCity);
}
}
Chromosome child= new Chromosome(listChild);
return child;
}
我尝试在任何地方添加同步但没有任何作用...所以我想知道问题在哪里,我该如何纠正? 谢谢!
答案 0 :(得分:2)
您无法从当前正在迭代的集合中删除,除非您使用Iterator.remove()
方法,这要求您不使用增强型for循环。
答案 1 :(得分:0)
在您的代码中,您不断重复使用相同的城市以及相同的列表。当您使用subList时,实际上是在旧列表(http://docs.oracle.com/javase/7/docs/api/java/util/List.html#subList(int, int]))上创建视图。毫无疑问,当您同时处理所有这些列表时,会出现ConcurrentModificationException。
你必须非常小心这些列表(要真正看到它出错的地方,我们可能需要整个源代码)。或者您必须创建新的List实例而不是subList。
顺便说一句,你翻译一半法语的方式使你不太容易阅读你的代码而不是更容易..(pere-father,child-fils等..)