Когда я пытался применить алгоритм GA, я обнаружил проблему: я копирую значение из списка A в другой B и манипулирую B. Но когда я запускал модульный тест. Я просто обнаружил, что оба значения A и B изменились. И я понятия не имею, что случилось. Ниже мой код:
public class GA_bags {
private Population population;
private int fittest;
private List<Individual> offsprings;
public GA_bags(int n,int sumBags,int maxWeight,Bag[] bags){
this.population=new Population(n,sumBags,maxWeight,bags);
}
//Crossover Function
public void crossover(){
Random random=new Random();
List<Individual> individuals=population.getIndividuals();
offsprings=new ArrayList<>(individuals); //Intialize the offsprings, simply copy first
int pos=random.nextInt(offsprings.get(0).getGenes().length); //decide the position of genes to crossover
for(int i=0;i<offsprings.size()-1;i+=2){ //1st fittest pair with 2nd fittest,3nd with the 4th...
for(int j=0;j<=pos;j++){
int tem=offsprings.get(i).getGenes()[j];
offsprings.get(i).getGenes()[j]=offsprings.get(i+1).getGenes()[j];
offsprings.get(i+1).getGenes()[j]=tem;
}
}
}
После того, как я реализовал метод кроссовера, изменились как отдельные лица, так и потомки List, но я управлял только потомками List.
public class Individual {
//each individual is a solution of KnapsackProblem
private int[] genes; //"1" stands for the bag is chosen, while "0" stands for the bag is not
private Bag[] bags; //each digit of gene is responsible for a specific Bag object
private int fitness; //the fitness of an individual
private int curWeight; //the weight of this individual
private int maxWeight; //once the total weight of bags of this individual over maxWeight, then fitness is 0
public Individual(int sumBags,int maxWeight,Bag[] bags){
this.genes=new int[sumBags];
this.maxWeight=maxWeight;
this.bags=bags;
Random random=new Random();
for(int i=0;i<sumBags;i++){
genes[i]=random.nextInt(2); //genetic code: random generate genes,"0" or "1"
}
}
}
Так как мне это изменить?
Большое спасибо!




Речь идет о глубоком копировании, и здесь является примером.
Если вы хотите скопировать примитивный тип, вы можете просто использовать =. Если вы хотите скопировать объект, = просто заставит переменную указывать на адрес объекта. Таким образом, обе переменные указывают на один и тот же объект.
Если вы хотите, чтобы новая переменная указывала на совершенно новый объект, вам нужно скопировать его самостоятельно. Самый простой способ - скопировать примитивные атрибуты один за другим.
Я опередил тебя на секунду (как комментарий, как и должно быть)
Хороший ответ был бы более содержательным и самодостаточным.
Большое спасибо!
Привет, ScaryWombat, rustyx, я понял свою точку зрения и добавил некоторые пояснения.
offsprings=new ArrayList<>(individuals);не собирается создавать объектыnewIndividual- они указывают на одни и те же объекты