2012-04-30 3 views
1

나는 간단한 유전자 알고리즘을 만들려고하는 순간에 프로젝트를 진행하고있다. 구조와 관련해서, 나는 4 개의 숫자를 가진 char [] 인 유전자와 10 개의 유전자 객체의 배열 인 염색체를 가지고 있습니다. 깊은 복사 및 유전자 알고리즘

나는 부모 염색체의 각 반에서 아이를 만드는 간단한 크로스 오버 메소드를 작성하려합니다. 나는 아래의 접근법으로 시작했지만 곧 내가 단지 얕은 복사임을 깨달았다. 지난 몇 일 동안 복제 가능한 인터페이스를 사용하여 많은 복사본을 읽는 데 많은 시간을 보냈지 만 모든 시도에서 실패했습니다. 누군가이 문제에 대해 저를 도울 수 있습니까? 모든 팁 및 포인터 grately 우리가 먼저 Gene 클래스를 생각해 보자

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;  
} 
+0

는'가변 genes' 있습니까? 다시 할당하지 않고 값을 수정할 수있는 연산이 있습니까? –

+0

안녕하세요, 보리스, 아이 염색체에 영향을 줄 뮤 테이터 클래스가 있습니다. 그래서 부모와 자식을위한 별도의 배열이 필요합니다. –

+0

예, 이미 별개의 배열입니다. 단지 그들이 동일한'.gene' 객체를 공유한다는 것입니다. 나는 아직도 이것이 어떤 문제를 일으키는 지 확신하지 못하고있다. 왜냐하면 나는'유전자 '의 가치를 변화시킬 작전을 생각할 수 없기 때문이다. 이 객체의 유형을 공유해 주시겠습니까? 그리고 당신이 선언 한 코드를 질문에 포함 시키시겠습니까? –

답변

2

을 감상 할 수있다 : 당신의 사양에 따라 (나는 [] 네 개의 숫자에 문자하는 유전자가), 당신이 char 배열과 필요를 클래스의 속성. 또한이 클래스는 복제 가능해야하며이 클래스는 Cloneable 인터페이스를 구현해야합니다. 즉, Gene 클래스는 Cloneable 인터페이스를 구현하고 (클래스 정의에 implements Cloneable을 작성하기 만하면 됨) 선언해야하며 clone을 구현해야합니다. 메서드를 호출해야합니다 (이 메서드에서는 개체 필드의 전체 복사본을 만들고 복제 된 개체를 반환해야합니다. 자세한 내용은 아래 코드를 참조하십시오). (배열 복사에 대한 자세한 내용은 here를 참조하시기 바랍니다) 나는 방법 Arrays 클래스의 copyOf을 사용하는 배열을 복사하는

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

참고.

간단한 테스트

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; 
    } 
} 
+0

안녕 enzom83, 정말 고마워요. 귀하의 솔루션을 통해 노력하고 있습니다. child.setGene (i, parentA.getGene (i)) 코드로 setGene 메소드가 Gene 클래스의 setUnit 메소드를 참조합니까? 이러한 setGene 및 getGene 메서드는 어떻게 표시되어야합니까? 죄송합니다. 프로그래밍에 매우 익숙합니다 (6 개월). 미리 감사드립니다. –

+0

죄송합니다. 모든 염색체 클래스를 동봉하는 것을 잊어 버렸습니다. 이제 추가했습니다. 곧 나는 나의 대답에 약간의 세부 사항을 더한다 – enzom83

+0

다시 한번 나의 친구에게 감사한다.나는 너의 포스트 때문에 지금 일하고 있다고 생각한다. –

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



    } 

나는 종자를 사용하고, 염색체의 수에 대한 카운트가 나는 피트니스 속성이 변수를 사용하기 때문이다.

관련 문제