变量(矩阵)改变其值 - Java

时间:2014-11-19 23:16:27

标签: java matrix multidimensional-array

我的代码出了问题。我有一个包含整数矩阵的对象,我使用这个矩阵作为原始"模型"创建其他矩阵。但最后,我的原始矩阵有不同的值,但我没有任何改变。

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

就是这样。

2 个答案:

答案 0 :(得分:0)

当你这样做时......

int[][] auxiliar_matrix = mc.matrixStructure.matrix;
int[] original_ordering = mc.matrixStructure.matrixOrder;

...您正在对auxiliar_matrixoriginal_ordering引用的相同对象进行mc.matrixStructure.matrixmc.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 - 副本很浅,它只会复制对子数组的引用,这会给你带来同样的问题。