我正在尝试实现TSP双桥移动,其工作方式如下: 给定城市的排列(游览),它将排列分成4个部分,并以不同的顺序重新连接这些部分。 例如perm = [a,b,c,d] --->并[a,d,C,B]。
在下面的方法中,我有temp []数组,其中包含pemutation的城市。我选择3个随机数并将数组拆分为4个部分
public void doubleBridge() {
City[] temp = this.permArray; // it's a tour so the first element equals the last temp[0]=temp[temp.length-1]
Random random = new Random();
int pos1 = 1+ random.nextInt(temp.length/4);
int pos2 = pos1 + 1 + random.nextInt(temp.length/4);
int pos3 = pos2 + 1 + random.nextInt(temp.length/4);
System.out.println("\nPositions chosen : "+pos1+" "+pos2+" "+pos3);
City[] part1 = new City[pos1+1];
part1 = Arrays.copyOfRange(temp, 0, pos1);
City[] part2 = new City[pos2-pos1-1];
part2= Arrays.copyOfRange(temp, pos1+1, pos2);
City[] part3 = new City[pos3-pos2-1];
part3= Arrays.copyOfRange(temp, pos2+1, pos3);
City[] part4 = new City[temp.length-1-pos3-1];
part4= Arrays.copyOfRange(temp, pos3+1, temp.length);
//City[] newTemp = new City[temp.length];
System.out.println("\npart1");
for (City c: part1) {
System.out.print(c.getId()+" ");
}
System.out.println("\npart2");
for (City c: part2) {
System.out.print(c.getId()+" ");
}
System.out.println("\npart3");
for (City c: part3) {
System.out.print(c.getId()+" ");
}
System.out.println("\npart4");
for (City c: part4) {
System.out.print(c.getId()+" ");
}
/*newTemp = concatAll(part1, part2, part3, part4);
this.permArray = newTemp;
this.computePermutationLength();*/
}
运行程序后,打印出我得到的部件。
{38,18,27,2,20,35,1,42,50,22,52,36,44,31,19,33,3,25,29,49,12,4,7, 30,43,24,48,45,26,39,11,15,21,34,28,8,13,51,41,17,10,37,46,32,16,23,14,5, 9,6,47,40,38,} LENGTH:23511950
选择的职位:3 12 24
part1的 38 18 27
2部分 20 35 1 42 50 22 52 36
第3部分 31 19 33 3 25 29 49 12 4 7 30
第四部分 24 48 45 26 39 11 15 21 34 28 8 13 51 41 17 10 37 46 32 16 23 14 5 9 6 47 40 38
问题在于丢失了4个元素。例如:初始排列中的元素“2”在part1或part2中都不存在。
那么问题出在哪里?
答案 0 :(得分:2)
目前尚不清楚您是否希望“2”成为part1或part2的一部分,但请查看代码:
City[] part1 = new City[pos1+1];
part1 = Arrays.copyOfRange(temp, 0, pos1);
City[] part2 = new City[pos2-pos1-1];
part2= Arrays.copyOfRange(temp, pos1+1, pos2);
此处pos1
处的元素不属于part1
,因为copyOfRange
的最后一个参数是 exclusive 。这是典型的Java API - 例如"012345".substring(0, 3)
将为您提供“012”,而不是“0123”。
它不属于part2
,因为您以<{1}}开始。
基本上,这两个参数应该匹配。目前尚不清楚它们应该是pos1+1
还是pos1 + 1
,但它们应该匹配。
答案 1 :(得分:0)
尝试Arrays.copyOfRange(temp, pos1, pos2);
等,而不在启动参数中添加1。
答案 2 :(得分:0)
从Arrays.copyOfRange docs开始,参数为:
所以你应该有以下四行:(开始/来自索引不应该增加)
City[] part1 = new City[pos1+1];
part1 = Arrays.copyOfRange(temp, 0, pos1);
City[] part2 = new City[pos2-pos1-1];
part2= Arrays.copyOfRange(temp, pos1, pos2);
City[] part3 = new City[pos3-pos2-1];
part3= Arrays.copyOfRange(temp, pos2, pos3);
City[] part4 = new City[temp.length-1-pos3-1];
part4= Arrays.copyOfRange(temp, pos3, temp.length);
此致 斯特凡
答案 3 :(得分:0)
在上面的代码中
City[] part1 = new City[pos1+1];
part1 = Arrays.copyOfRange(temp, 0, pos1);
City[] part2 = new City[pos2-pos1-1];
part2= Arrays.copyOfRange(temp, pos1+1, pos2);
在part1 = Arrays.copyOfRange(temp,0,pos1);中,数组被复制到pos-1 而在part2 = Arrays.copyOfRange(temp,pos1 + 1,pos2); ,pos1中的元素被遗漏,因为正在复制的数组部分是从pos1 + 1
开始的