提问者:小点点

我的Java遗传算法实现似乎围绕着中间层适应值而不是高值


我的遗传算法实现了一个名为gene的类,它存储一个100(trigit?)三元字符串(最初是二进制的,但尝试了三元)。我提供了一种评估基因适合度的方法(所有数字的总和,因此222…222将是最优的)。我最初认为适合度等于基因与给定序列的匹配程度,但后来改变了它。我还提供了一种“突变”基因的方法。在一定的概率下,基因中的每个条目都可以突变为3个可能密码子中的一个。

我从初始种群开始。我找到适者生存的人,杀死其他人,复制适者生存的人(“完美”有丝分裂,突变只发生在下一步),然后突变所有的基因。我运行这个很多“时代”。

最大适应度是200,但我的算法似乎以90-110为中心,作为每个时代的最高适应度。如果我随机生成起始基因,我的最高适应度大约在120左右,但很快就会回到90-110(在1-2个时期内)。其他GA实现没有这个问题。我做错了什么?Java源代码粘贴在底部。

    import java.util.Random;

    public class Gene {

int[] gene=new int[100];

public Gene() {

Random rand=new Random();
 for(int i=0; i<100; i++){

    gene[i]=rand.nextInt(3);
}
}

public int fitness(){

    int sum=0;
    for(int i=0; i<gene.length; i++){
        sum=sum+gene[i];
    }
    return sum;
}
public void mutate(){

    Random randP=new Random();
    Random randM=new Random();
    for(int i=0; i<gene.length; i++){
        if(randP.nextInt(1000)<1){gene[i]=randM.nextInt(3);}
    }


}
public int compareTo(Gene g){
    return this.fitness()-g.fitness();
}
public String toString(){
    return ""+this.fitness();
}
public void minFit(){
    for(int i=0; i<gene.length; i++){
        gene[i]=0;
    }
}
public void maxFit(){
    for(int i=0; i<gene.length; i++){
        gene[i]=2;
    }
}

    }



    public class Biome {



        public static void main(String[] args) {
        Gene[] species=new Gene[1000];
        for(int i=0; i<1000; i++){
    species[i]=new Gene();
    species[i].maxFit();
}
int epoch=0;
System.out.println("start");
while(epoch<1000){
    System.out.println(fittestGene(species));
    sort(species);
    for(int i=0; i<999; i++){species[i]=species[999];}
    for(int i=0; i<1000; i++){species[i].mutate();}
    epoch++;


}



}
public static Gene fittestGene(Gene[] g){
    int maxIndex=0;
    for(int i=0; i<g.length; i++){
        if(g[i].fitness()>g[maxIndex].fitness()){maxIndex=i;}
    }
    return g[maxIndex];
}
public static void swap(Gene[] g, int a, int b){
    Gene temp=g[a];
    g[a]=g[b];
    g[b]=temp;
}
public static void sort(Gene[] g){
    for(int i=0; i<g.length; i++){
        int minIndex=i;
        for(int j=i+1; j<g.length; j++){
         if(g[j].compareTo(g[minIndex])>0){swap(g, j, minIndex);}
        }
    }
}

    }

共1个答案

匿名用户

这似乎是错误的地方:

for(int i=0; i<999; i++){species[i]=species[999];}

数组保存对基因对象的引用。因此,在该行之后,数组中的所有引用都指向相同的Gene对象。

您将只有1个基因,它的适应值将由均匀分布在0和2之间的100个整数之和组成。这就是90-110值的来源。

要正确复制基因,您需要为gene定义一个复制构造函数,并使用该构造函数:

public class Gene {
    ...
    public Gene(Gene other) {
        this.gene = Arrays.copyOf(other.gene, other.gene.length);
    }
}

然后将原始行更改为:

for(int i=0; i<999; i++){species[i]=new Gene(species[999]);}