是的,我正在为一个大学项目做GA算法,但是在做Crossover时,我注意到我的个人长度已经改变,应该是100。
我正在创建一个包含100个City对象的ArrayList(这是Traveling Salesman的一个版本),并从中创建100个Id编号的路径,并将其传递给String []。 id从0到99。但是,当我使用Collections类对它们进行混洗时,它在对它们进行混洗,但是它也是重复的条目。这是代码。
Random r = new Random(seed);
for (int i = 0; i < popSize; i++){ // popSize is population size which is 100 normally
Collections.shuffle(baseInd, r); //baseInd is the ArrayList of 100 City objects
for (int ii = 0; ii < baseInd.size(); ii++){
indPath[ii] += String.valueOf(baseInd.get(ii).getID() + "."); // This is getting the current baseInd and outputting the ID to a String.
}
indDist[i] = Double.toString(calculateDistance(baseInd)); //method to calculate the distance from start to end on a individual.
}
这是当前的样本输出(我只发布前3个,因为它已经绕了很久),并且我已经粗体显示了一两个重复。可能还有更多,但太多了!
0:60 + 74 + 94 + 39 + 13 + 76 + 42 + 60 + 59 + 27 + 3 + 19 + 13 + 44 + 90 + 33 + 3 + 84 + 94 + 66 + 26 + 15 + 30 + 65 + 75 + 37 + 82 + 86 + 97 + 60 + 54 + 10 + 72 + 22 + 87 + 59 + 68 + 82 + 58 + 33 + 94 + 13 + 70 + 58 + 54 + 31 + 93 + 25 + 91 + 10 + 94 + 14 + 89 + 73 + 39 + 67 + 12 + 41 + 99 + 46 + 28 + 62 + 32 + 96 + 37 + 46 + 9 + 81 + 33 + 36 + 42 + 77 + 1 + 21 + 39 + 61 + 41 + 81 + 23 + 73 + 42 + 13 + 66 + 35 + 51 + 64 + 2 + 11 + 96 + 87 + 75 + 24 + 50 + 8 + 86 + 52 + 32 + 35 + 73 + 77+
距离:13781 + 834427040787
1:2 + 89 + 43 + 7 + 58 + 32 + 71 + 44 + 96 + 63 + 2 + 57 + 12 + 34 + 53 + 43 + 94 + 14 + 97 + 18 + 91 + 40 + 18 + 86 + 46 + 70 + 46 + 46 + 46 + 98 + 50 + 0 + 45 + 44 + 94 + 34 + 17 + 89 + 72 + 1 + 9 + 99 + 40 + 97 + 88 + 3 + 12 + 38 + 5 + 41 + 2 + 26 + 74 + 96 + 33 + 33 + 29 + 16 + 74 + 18 + 10 + 13 + 96 + 12 + 16 + 76 + 77 + 2 + 0 + 89 + 18 + 36 + 88 + 56 + 35 + 33 + 28 + 88 + 35 + 86 + 61 + 98 + 99 + 66 + 31 + 90 + 23 + 86 + 45 + 74 + 2 + 88 + 80 + 84 + 19 + 33 + 81 + 23 + 90 + 37岁以上
距离:14157 + 066270019255
2:69 + 13 + 20 + 68 + 8 + 80 + 58 + 26 + 57 + 1 + 45 + 73 + 83 + 13 + 32 + 58 + 10 + 17 + 76 + 25 + 99 + 29 + 28 + 31 + 68 + 95 + 88 + 91 + 19 + 22 + 86 + 97 + 75 + 64 + 1 + 49 + 19 + 88 + 55 + 96 + 3 + 62 + 23 + 45 + 31 + 63 + 39 + 52 + 70 + 70 + 35 + 2 + 86 + 49 + 34 + 49 + 7 + 2 + 72 + 37 + 37 + 81 + 46 + 23 + 82 + 7 + 35 + 65 + 74 + 64 + 80 + 43 + 48 + 3 + 5 + 46 + 35 + 30 + 94 + 55 + 47 + 45 + 79 + 83 + 58 + 40 + 95 + 94 + 98 + 84 + 28 + 94 + 61 + 87 + 1 + 40 + 83 + 55 + 18 + 74岁以上
距离:13178 + 332276530997
}
我确保baseInd仅包含0到99的一次出现。
for (int a = 0; a < baseInd.size(); a++){
System.out.print(baseInd.get(a).getID() + "+");
}
肯定是(也许是!)正在造成它的洗牌。有任何想法吗?
-更多代码----
这是创建City对象的方法。它从.csv文件读取。我不关心这个,因为上面的代码在任何洗牌之前会打印0到99。
public static ArrayList<City> createBaseInd(ArrayList<City> baseInd){
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader("towns.csv"));
String line;
String[] lines;
while ((line = reader.readLine()) != null)
{
lines = line.split(",");
baseInd.add(new City(lines[0], Double.parseDouble(lines[1]), Double.parseDouble(lines[2]), Integer.parseInt(lines[3]))); //Struct is Name, X Co Ord, Y Co Ord, ID
}
reader.close();
} catch (IOException e) {
System.out.println("file not found");
e.printStackTrace();
}
return baseInd;
}
我没有什么能真正添加与该问题相关的信息,因为在创建baseInd之后,该问题在输出的这一点上发生,并且尚未对输出进行编辑(通过突变或交叉)。
最佳答案
您应该在内部循环中从以下位置更改索引
indPath[ii] += String.valueOf(baseInd.get(ii).getID() + ".");
至
indPath[i] += String.valueOf(baseInd.get(ii).getID() + ".");
让我们看一个简单的示例,其中
popSize
是2
,而shuffle
产生[1, 2]
两次:在外循环的第一次迭代之后,
indPath[0] => 1.
indPath[1] => 2.
在外循环的第二次迭代之后,
indPath[0] => 1.1.
indPath[1] => 2.2.
这两个路径都包含重复项。