1

現在、単純な遺伝的アルゴリズムを作成しようとするプロジェクトに取り組んでいます。構造に関しては、4 つの数字を持つ char [] である遺伝子と、10 個の遺伝子オブジェクトの配列である染色体があります。

親染色体のそれぞれの半分から子を作成する単純なクロスオーバー メソッドを作成しようとしています。以下のアプローチから始めましたが、すぐに浅いコピーに過ぎないことに気付きました。ここ数日、複製可能なインターフェイスを使用してディープ コピーを実装する方法に関する多数の投稿を読んできましたが、すべての試みで成功していません。誰かがこの問題で私を助けてください。ヒントや指針をいただければ幸いです

public Chromosome createChild (Chromosome parentA, Chromosome parentB)
{
    Chromosome child=new Chromosome();
    for (int i=0;i<10; i++)
    {   
        if (i<5)
        {
            child.genes[i] = parentA.genes[i]; 
        }
        else
        {
            child.genes[i] = parentB.genes[i];
        }

    }   
    return child;       
}
4

2 に答える 2

2

最初にクラスを考えてみましょうGene: あなたの仕様 ( 4 つの数字を持つ char [] である Gene がありますchar) によると、クラスの属性として配列が必要です。さらに、このクラスは複製可能でなければなりません。次に、このクラスにインターフェースを実装させる必要があります。この目的のために、クラスがインターフェースを実装Cloneableすることを宣言し(単にクラス定義に書き込むだけです) 、このクラスにメソッドを実装する必要があります(このメソッドでは、オブジェクト フィールドのディープ コピーを作成し、複製されたオブジェクトを返す必要があります。詳細については、以下のコードを参照してください)。GeneCloneableimplements Cloneableclone

import java.util.Arrays;

/*
 * Definition of the class that also includes the declaration
 * of the implementation of the Cloneable interface.
 */
public class Gene implements Cloneable {

    /*
     * The length of a gene.
     * It is defined as constant (final) in order to use the same value
     * in the whole class, where and when necessary.
     */
    private static final int GENE_LENGTH = 4;

    /*
     * In biology a gene it corresponds to a sequence of nucleic acids,
     * so I thought of naming m_sequence this field.
     */
    private char m_sequence[];

    /*
     * This constructor allows you to instantiate a new object from a char array.
     */
    public Gene(char sequence[]) {
        // The field m_sequence is initialized with a copy
        // of the array specified in the constructor.
        m_sequence = Arrays.copyOf(sequence, GENE_LENGTH);
    }

    /*
     * Simple getter method.
     * Since m_sequence is private, you need a method like this
     * in order to access elements of the array.
     */
    public char getUnit(int index) {
        return m_sequence[index];
    }

    /*
     * Simple setter method.
     * Since m_sequence is private, you need a method like this
     * in order to set the elements of the array.
     */
    public void setUnit(int index, char unit) {
        m_sequence[index] = unit;
    }

    /*
     * The Cloneable declaration requires that this class has clone method.
     * This method should return an Gene object within an Object.
     */
    protected Object clone() throws CloneNotSupportedException {
        // First, we invoke the clone method of the superclass
        Gene clone = (Gene)(super.clone());

        // Then, make the deep copy of the object.
        // In this case the only field present in the Gene object is an array,
        // then you must make a deep copy of this array: in order to make a deep
        // copy of the array, you should use the Arrays.copyOf method.
        clone.m_sequence = Arrays.copyOf(m_sequence, GENE_LENGTH);

        return clone;
    }

    /*
     * Get a representation of this object as a String.
     * Just a method for simple testing.
     */
    @Override
    public String toString() {
        return Arrays.toString(m_sequence);
    }
}

copyOf配列をコピーするためにクラスのメソッドを使用したことに注意してください (配列のコピーの詳細については、こちらArraysをお読みください)。

Geneオブジェクトのディープ コピーの機能を確認する簡単なテスト:

public static void main(String args[]) throws CloneNotSupportedException {
    Gene g1 = new Gene(new char[]{'a', 'b', 'c', 'd'});
    Gene g2 = (Gene)(g1.clone());

    // now Let's modify g1
    g1.setUnit(0, 'e');
    g1.setUnit(1, 'f');
    g1.setUnit(2, 'g');
    g1.setUnit(3, 'h');

    System.out.println("g1: " + g1);
    System.out.println("g2: " + g2);   // g2 has not changed
}

したがって、次のようにcreateChildメソッドを変更する必要があります。

public class Chromosome {
    private static final int CHROMOSOME_LENGTH = 10;

    /* Array of Gene object. */
    private Gene genes[];

    /* Default constructor. */
    public Chromosome() {
        // Simply allocates an array of 10 elements.
        genes = new Gene[CHROMOSOME_LENGTH];
    }

/*
     * Simple getter method.
     * Since m_Genes is private, you need a method like this
     * in order to access elements of the array.
     */
    public Gene getGene(int index) {
        return genes[index];
    }

/*
     * Simple setter method.
     * Since m_Genes is private, you need a method like this
     * in order to set the elements of the array.
     */
    public void setGene(int index, Gene gene) {
        genes[index] = gene;
    }

    /* The method which make the cross-over. */
    public Chromosome createChild(Chromosome parentA, Chromosome parentB) throws CloneNotSupportedException {
        Chromosome child = new Chromosome();

        // make the cross-over
        for (int i=0;i<10; i++)
        {   
            if (i<5)
            {
                // you need to call the clone() method
                child.genes[i] = (Gene)(parentA.genes[i].clone());
            }
            else
            {
                // you need to call the clone() method
                child.genes[i] = (Gene)(parentB.genes[i].clone());
            }
        }

        return child;
    }
}
于 2012-04-30T10:19:42.517 に答える
0

調査プロジェクトのクロスオーバーに次のコードを使用しました。多分それはあなたを助けることができます。

 package geneticSource;

import java.util.*;
import java.util.Random;

public class Crossover { 
//                                          //Var for seeds
private Random rdn;            
private Random rdn2;
private Random rdn3;
private double PROB_CROSS=1;

public Crossover(double value,int seed){
    this.PROB_CROSS=value;  
    this.rdn= new Random(seed);
    this.rdn2= new Random(seed+1);
    this.rdn3= new Random(seed+2);
}



public Population Cross(Population p){
    int pointCross=0;        //Crossover point
    int n1=0;                
    int n2=0;
    double probCross=0;
    double probMut=0;
    Chromosome cr1=null;
    Chromosome cr2=null;
    List<Gen> mum1=new LinkedList<Gen>();
    List<Gen> dad1=new LinkedList<Gen>();
    List<Gen> mum2=new LinkedList<Gen>();
    List<Gen> dad2=new LinkedList<Gen>();
    ArrayList<Gen> geno1=new ArrayList<Gen>();
    ArrayList<Gen> geno2=new ArrayList<Gen>();
    Population pnew = new Population();
    //Integer[] cruce=new Integer [p.population.size()];
    ArrayList <Integer>cruceControl=new ArrayList<Integer>();
    for(int i=0;i<p.population.size();i++){
        cruceControl.add(i);
    }
    int aux=0;
    for(int i=0;i<p.population.size()/2;i++){

        n1=rdn.nextInt(cruceControl.size());
        aux=cruceControl.get(n1);
        cruceControl.remove(n1);    
        n1=aux;
        n2=rdn.nextInt(cruceControl.size());
        aux=cruceControl.get(n2);
        cruceControl.remove(n2);
        n2=aux;

        mum1=new LinkedList<Gen>();
        dad1=new LinkedList<Gen>();
        mum2=new LinkedList<Gen>();
        dad2=new LinkedList<Gen>();
        geno1=new ArrayList<Gen>();
        geno2=new ArrayList<Gen>();
        cr1=p.population.get(n1);
        cr2=p.population.get(n2);   

        probCross=this.rdn3.nextDouble();   
        probMut =this.rdn2.nextDouble();    
        if(probCross<=PROB_CROSS){               
            pointCross=rdn.nextInt(p.population.get(0).getChromosome().size());
            mum1=cr1.getChromosome().subList(0,pointCross );
            dad1=cr1.getChromosome().subList(pointCross,cr1.getChromosome().size() );
            mum2=cr2.getChromosome().subList(0,pointCross );
            dad2=cr2.getChromosome().subList(pointCross,cr2.getChromosome().size() );
            //cross;
            geno1.addAll(mum1);
            geno1.addAll(geno1.size(), dad2);
            geno2.addAll(mum2);
            geno2.addAll(geno2.size(), dad1);

            //Update the number for chromosome
            int Nva1=0;
            int Nva2=0;
            for(int j=0;j<geno1.size();j++){
                if(geno1.get(j).getValue()==1)Nva1++;
                if(geno2.get(j).getValue()==1)Nva2++;
            }
            p.population.set(n1, new Chromosome(geno1));
            p.population.get(n1).setNVariables(Nva1);
            p.population.set(n2, new Chromosome(geno2));
            p.population.get(n2).setNVariables(Nva2);
            if(Nva1<p.fminV) p.fminV=Nva1;
            if(Nva2<p.fminV) p.fminV=Nva2;
            if(Nva1>p.fmaxV) p.fmaxV=Nva1;
            if(Nva2>p.fmaxV) p.fmaxV=Nva2;

        }


    }
    int k=0;
    for(Chromosome c : p.getPopulation()){
        k=0;
        for(Gen g : c.getChromosome())
            if(g.getValue()==1)k++;
                    if(k!=c.getNVariables())System.out.println(".................................................................");
    }


    return p;
    }



  }

この変数をフィットネス属性に使用したため、シードと染色体数のカウントを使用しました。

于 2014-12-17T19:37:40.847 に答える