You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

交叉操作后列表仅保留最后两个Chromosome的问题求助

遗传算法交叉操作:列表仅保留最后两个Chromosome的问题解决

嘿,我仔细瞅了你的代码,终于找到问题所在了!你每次循环生成新Chromosome时,虽然看起来是创建了新的对象,但实际上所有Chromosome都共享了同一个数组引用——因为newGenes1和newGenes2是在for循环外面定义的。

每次循环你只是修改这两个数组里的元素值,而不是创建新的数组。当你把这两个数组传给Chromosome构造函数时,所有生成的Chromosome对象都会指向这两个数组的内存地址。循环结束后,数组里存的是最后一次循环修改的值,所以你查看整个列表时,所有元素看起来都是最后生成的那两个Chromosome。

解决方法很简单:把数组定义移到循环内部

每次循环都创建新的数组实例,这样每个Chromosome都会持有独立的数组引用,不会互相覆盖。修改后的代码如下:

public Population crossoverChromosomes(Population population, List<Item> items, int capacityOfKnapsack) { 
    Random rand = new Random(); 
    List<Chromosome> chromosomeList = new ArrayList<>(population.getChromosomeList()); 
    int genesLength = population.chromosomeList.get(0).getGenes().length; 
    ArrayList<Chromosome> newCrossoverPopulation = new ArrayList<>(); 

    for (int j = 0; j < population.getPopulationSize() / 2; j++) { 
        // 把数组定义移到循环内部,每次循环创建新数组
        int newGenes1[] = new int[genesLength]; 
        int newGenes2[] = new int[genesLength]; 

        int firstChrIndex = rand.nextInt(population.getPopulationSize()); 
        int secondChrIndex = rand.nextInt(population.getPopulationSize()); 
        int d = rand.nextInt(genesLength); // 这里建议改用基因长度,避免超出数组索引范围

        Chromosome firstChr = chromosomeList.get(firstChrIndex); 
        Chromosome secondChr = chromosomeList.get(secondChrIndex); 

        for (int i = 0; i < genesLength; i++) { 
            if (i < d) { 
                newGenes1[i] = firstChr.getGenes()[i]; 
                newGenes2[i] = secondChr.getGenes()[i]; 
            } else { 
                newGenes1[i] = secondChr.getGenes()[i]; 
                newGenes2[i] = firstChr.getGenes()[i]; 
            } 
        } 

        Chromosome chr1 = new Chromosome(genesLength, newGenes1); 
        Chromosome chr2 = new Chromosome(genesLength, newGenes2); 

        chr1.fitnessCalculate(items, capacityOfKnapsack); 
        newCrossoverPopulation.add(chr1); 

        chr2.fitnessCalculate(items, capacityOfKnapsack); 
        newCrossoverPopulation.add(chr2); 
    } 

    return new Population(newCrossoverPopulation.size(), newCrossoverPopulation); 
}

额外小优化

我还帮你调整了两个小细节:

  • 生成索引时改成rand.nextInt(population.getPopulationSize()),这样能取到种群的最后一个元素(原代码会永远跳过最后一个索引)
  • 交叉点d改用基因长度作为范围,避免出现d大于基因长度导致数组越界的问题

内容的提问来源于stack exchange,提问作者senham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:36:04