Java 克隆方法无效
Java cloning method does not work
我把我的程序目前最好的方案复制如下:
public Object clone()
{
MySolution copy = (MySolution)super.clone();
copy.wtour = (int[])this.wtour.clone();
copy.w = (int[][][][])this.w.clone();
return copy;
}
当我最后请求整体最佳解决方案时,程序总是给我当前的最佳解决方案,但从来没有提供具有最佳 objective 值的解决方案。此外,如果我从我的程序中排除规定的部分,解决方案也不会改变。
编辑:它是禁忌搜索优化器的一部分,可生成解决方案并保存新的当前最佳解决方案(如此处)
clone 方法保存路由问题的路线,其中 w[][][][] 是一个二元决策变量,wtour 是它的一个副本,但由访问序列中的客户编号组成,即 [0, 5, 3 , 2, 1, 4].
编辑:
我根据 Robby Cornelissen 修改了我的程序如下:
public Object clone() {
MySolution copy = (MySolution)super.clone();
copy.w = copy2(w);
return copy;
}
public static int[][][][] copy2(int[][][][] source) {
int[][][][] target = source.clone();
for (int i = 0; i < source.length; i++) {
target[i] = source[i].clone();
for (int j = 0; j < source[i].length; j++) {
target[i][j] = source[i][j].clone();
for (int q = 0; q < source[i][j][q].length; q++) {
target[i][j][q] = source[i][j][q].clone();
}
}
}
return target;
}
结果,我得到了一个克隆如下:
w[0][5][1][0]=1
w[4][2][2][0]=1
w[2][5][3][0]=1
w[5][0][4][0]=1
w[0][4][1][1]=1
w[6][1][2][1]=1
w[1][3][3][1]=1
w[3][0][4][1]=1
现在的问题是只有第一个元素属于最佳解(w[0][5][1][0])。为什么其他的没有被复制?
解决方案:
我按照提供的 link 建议更改了我的程序:
public Object clone()
{
MySolution copy = (MySolution)super.clone();
copy.w = deepCopyOf(w);
return copy;
} // end clone
@SuppressWarnings("unchecked")
public static <T> T[] deepCopyOf(T[] array) {
if (0 >= array.length) return array;
return (T[]) deepCopyOf(
array,
Array.newInstance(array[0].getClass(), array.length),
0);
}
private static Object deepCopyOf(Object array, Object copiedArray, int index) {
if (index >= Array.getLength(array)) return copiedArray;
Object element = Array.get(array, index);
if (element.getClass().isArray()) {
Array.set(copiedArray, index, deepCopyOf(
element,
Array.newInstance(
element.getClass().getComponentType(),
Array.getLength(element)),
0));
} else {
Array.set(copiedArray, index, element);
}
return deepCopyOf(array, copiedArray, ++index);
}
问题如下:
- 当您
clone
基元数组时,将克隆数组对象及其值。
- 当您
clone
一个对象数组时,该数组对象被克隆,但克隆的数组将包含对原始数组中包含的相同对象的引用。
现在这对你的情况意味着什么?
- 您的
wtour
值似乎是一个包含 primitive int
的数组,因此上述两种情况中的第一种适用。 IE。数组及其内容都被有效地复制了。
- 您的
w
值似乎是 int
的多维数组。实际上,这意味着它实际上是一个包含数组 objects 的数组,因此适用第二种情况。尽管复制了您的顶级数组对象,但复制的数组包含对与原始数组相同的二级数组对象的引用。
讨论了类似的问题和可能的解决方案 here。
更新
按照评论中的要求,一个简单的实现可能如下所示。请注意,这是完全未经测试的:
public static int[][][] copy(int[][][] source) {
int[][][] target = source.clone();
for (int i = 0; i < source.length; i++) {
target[i] = source[i].clone();
for (int j = 0; j < source[i].length; j++) {
target[i][j] = source[i][j].clone();
}
}
return target;
}
我把我的程序目前最好的方案复制如下:
public Object clone()
{
MySolution copy = (MySolution)super.clone();
copy.wtour = (int[])this.wtour.clone();
copy.w = (int[][][][])this.w.clone();
return copy;
}
当我最后请求整体最佳解决方案时,程序总是给我当前的最佳解决方案,但从来没有提供具有最佳 objective 值的解决方案。此外,如果我从我的程序中排除规定的部分,解决方案也不会改变。
编辑:它是禁忌搜索优化器的一部分,可生成解决方案并保存新的当前最佳解决方案(如此处) clone 方法保存路由问题的路线,其中 w[][][][] 是一个二元决策变量,wtour 是它的一个副本,但由访问序列中的客户编号组成,即 [0, 5, 3 , 2, 1, 4].
编辑: 我根据 Robby Cornelissen 修改了我的程序如下:
public Object clone() {
MySolution copy = (MySolution)super.clone();
copy.w = copy2(w);
return copy;
}
public static int[][][][] copy2(int[][][][] source) {
int[][][][] target = source.clone();
for (int i = 0; i < source.length; i++) {
target[i] = source[i].clone();
for (int j = 0; j < source[i].length; j++) {
target[i][j] = source[i][j].clone();
for (int q = 0; q < source[i][j][q].length; q++) {
target[i][j][q] = source[i][j][q].clone();
}
}
}
return target;
}
结果,我得到了一个克隆如下:
w[0][5][1][0]=1
w[4][2][2][0]=1
w[2][5][3][0]=1
w[5][0][4][0]=1
w[0][4][1][1]=1
w[6][1][2][1]=1
w[1][3][3][1]=1
w[3][0][4][1]=1
现在的问题是只有第一个元素属于最佳解(w[0][5][1][0])。为什么其他的没有被复制?
解决方案: 我按照提供的 link 建议更改了我的程序:
public Object clone()
{
MySolution copy = (MySolution)super.clone();
copy.w = deepCopyOf(w);
return copy;
} // end clone
@SuppressWarnings("unchecked")
public static <T> T[] deepCopyOf(T[] array) {
if (0 >= array.length) return array;
return (T[]) deepCopyOf(
array,
Array.newInstance(array[0].getClass(), array.length),
0);
}
private static Object deepCopyOf(Object array, Object copiedArray, int index) {
if (index >= Array.getLength(array)) return copiedArray;
Object element = Array.get(array, index);
if (element.getClass().isArray()) {
Array.set(copiedArray, index, deepCopyOf(
element,
Array.newInstance(
element.getClass().getComponentType(),
Array.getLength(element)),
0));
} else {
Array.set(copiedArray, index, element);
}
return deepCopyOf(array, copiedArray, ++index);
}
问题如下:
- 当您
clone
基元数组时,将克隆数组对象及其值。 - 当您
clone
一个对象数组时,该数组对象被克隆,但克隆的数组将包含对原始数组中包含的相同对象的引用。
现在这对你的情况意味着什么?
- 您的
wtour
值似乎是一个包含 primitiveint
的数组,因此上述两种情况中的第一种适用。 IE。数组及其内容都被有效地复制了。 - 您的
w
值似乎是int
的多维数组。实际上,这意味着它实际上是一个包含数组 objects 的数组,因此适用第二种情况。尽管复制了您的顶级数组对象,但复制的数组包含对与原始数组相同的二级数组对象的引用。
讨论了类似的问题和可能的解决方案 here。
更新
按照评论中的要求,一个简单的实现可能如下所示。请注意,这是完全未经测试的:
public static int[][][] copy(int[][][] source) {
int[][][] target = source.clone();
for (int i = 0; i < source.length; i++) {
target[i] = source[i].clone();
for (int j = 0; j < source[i].length; j++) {
target[i][j] = source[i][j].clone();
}
}
return target;
}