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;
}