我的代码出了问题。我有一个包含整数矩阵的对象,我使用这个矩阵作为原始"模型"创建其他矩阵。但最后,我的原始矩阵有不同的值,但我没有任何改变。
public Matrix generateAdjacencyMatrix(Matrix m)
{
int storedValue;
int fitness;
int[][] auxiliar_matrix = mc.matrixStructure.matrix;
int[] original_ordering = mc.matrixStructure.matrixOrder;
for(int i=0;i<mc.matrixStructure.getMatrixSize();i++)
{
if(m.matrixOrder[i] != original_ordering[i]) //Only changes if the columns have changed
{
for(int j=0;j<mc.matrixStructure.getMatrixSize();j++)
{
storedValue = auxiliar_matrix[j][m.matrixOrder[i]];
auxiliar_matrix[j][m.matrixOrder[i]] = auxiliar_matrix[j][original_ordering[i]];
auxiliar_matrix[j][original_ordering[i]] = storedValue;
}
for(int j=0;j<mc.matrixStructure.getMatrixSize();j++)
{
storedValue = auxiliar_matrix[m.matrixOrder[i]][j];
auxiliar_matrix[m.matrixOrder[i]][j] = auxiliar_matrix[original_ordering[i]][j];
auxiliar_matrix[original_ordering[i]][j] = storedValue;
}
}
}
m.matrix = auxiliar_matrix;
m.setFitness(computeFitness(m.matrix));
return m;
}
这是创建其他矩阵的方法。对象&#34; mc&#34;包含我的原始矩阵(mc.matrixStructure.matrix),并且恰好在for循环之后,值不同。
我在构造函数方法上实例化这个对象:
public GeneticAlgorithm() throws IOException
{
this.r = new Random();
this.matingPool = new ArrayList<>(populationSize);
this.population = new ArrayList<>(populationSize);
this.nextGeneration = new ArrayList<>(populationSize);
this.mc = new MatrixCreator("CS4006_input_file2.txt");
this.mc.check0or1();
this.mc.checkDiagonalLine();
this.mc.checkSymmetry();
this.auxiliarVector = mc.matrixStructure.matrixOrder;
this.auxiliarMatrix = new Matrix(mc.matrixStructure.getMatrixSize());
this.matrixSize = mc.matrixStructure.getMatrixSize();
}
就是这样。
答案 0 :(得分:0)
当你这样做时......
int[][] auxiliar_matrix = mc.matrixStructure.matrix;
int[] original_ordering = mc.matrixStructure.matrixOrder;
...您正在对auxiliar_matrix
和original_ordering
引用的相同对象进行mc.matrixStructure.matrix
和mc.matrixStructure.matrixOrder
次引用。通过一组引用修改这些对象相当于通过另一组修改它们,因此与您的断言相反,您绝对会更改原始矩阵。为避免这种情况,您需要复制数组。
此外,你有auxiliar_matrix
这个问题,因为Java 2D数组是数组的数组,而数组也是对象。您需要执行该2D数组的深层副本,以避免修改原始对象。
这样的事情应该这样做:
int[] original_ordering = Arrays.copyOf(mc.matrixStructure.matrixOrder);
int[][] auxiliar_matrix = Arrays.copyOf(mc.matrixStructure.matrix);
int i;
for (i = 0; i < auxiliar_matrix.length; i += 1) {
auxiliar_matrix[i] = Arrays.copyOf(auxiliar_matrix[i]);
}
答案 1 :(得分:0)
将对象指定给引用变量时,请指定其引用。您不要将其复制到该引用。
因此,在诸如
之类的作业之后int[][] auxiliar_matrix = mc.matrixStructure.matrix;
您的auxiliar_matrix
引用变量现在引用mc.matrixStructure.matrix
引用的矩阵。
它是同一个矩阵,位于堆上。
现在,您正在更改auxiliar_matrix
引用的对象内的数据。例如,这里:
auxiliar_matrix[j][original_ordering[i]] = storedValue;
这意味着该值将在它和mc.matrixStructure.matrix
所指的矩阵中更改。
如果您想要处理原始矩阵的单独副本而不影响它,则必须先将其复制到新对象,然后将此副本分配给auxiliar_matrix
。在这种情况下,它是一个数组数组,因此您必须创建一个相同长度的新数组,并使用Arrays.copyOf
复制每个子数组。小心尝试在数组数组上使用Arrays.copyOf
- 副本很浅,它只会复制对子数组的引用,这会给你带来同样的问题。