Java克隆方法不起作用

时间:2015-06-12 03:58:37

标签: java cloning

我正在复制我的程序的当前最佳解决方案如下:

public Object clone() 
{   
    MySolution copy = (MySolution)super.clone();
    copy.wtour =    (int[])this.wtour.clone();
    copy.w =        (int[][][][])this.w.clone();

    return copy;
}

当我最终要求总体最佳解决方案时,程序总是给我当前最好的解决方案,但从来没有具有最佳目标值的解决方案。此外,如果我从程序中排除声明的部分,则解决方案没有任何变化。

编辑:它是禁忌搜索优化器的一部分,可生成解决方案并保存新的当前最佳解决方案(如此处) 克隆方法保存了路由问题的遍历,其中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);
}

1 个答案:

答案 0 :(得分:4)

问题如下:

  • 当你clone一个基元数组时,克隆数组对象及其值。
  • 当你clone一个对象数组时,克隆了数组对象,但克隆的数组将包含对原始数组中包含的相同对象的引用。

现在这对你的案件意味着什么?

  • 您的wtour值似乎是包含原始 int的数组,因此上述两种情况中的第一种情况适用。即数组及其内容都被有效复制。
  • 您的w值似乎是int s的多维数组。实际上,这意味着它实际上是一个包含数组对象的数组,因此第二种情况适用。虽然复制了顶级数组对象,但复制的数组包含对与原始数组相同的第二级数组对象的引用。

讨论了类似的问题和可能的解决方案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;
}