2014-03-03 34 views
0

我正在編寫一些東西來模擬進化,但有一個方程被測試來找到算法的數字。基本上它是,它創造GENERATIONOrganisms,其中有DNABITSint秒,它執行方程的演變

((dna[0] & i)/i) + ((dna[1] & i)/i)... 

,然後進行比較,要真正digitsum,和隊友的兩種生物具有最小差異。不過由於某種原因,一代​​人的平均差異開始在486,000/487,000附近,然後有時會下降,但總是回到這個範圍。什麼導致了這種行爲?

public class CodeEvolution { 
    public static final int DNABITS = 30; 
    public static final int MUTATION = 5; 
    public static final int PARENT = 1000; 

    public static final int GENERATION = 10; 

    public static final int TEST = 1000; 

    public static final int RETURNTHRESHOLD = 10; 

    public static Random rand = new Random(); 

    static boolean firsttime = true; 

    static Organism[] generation; 
    static int[] difference; 

    public static void main(String[] args) throws NumberFormatException, IOException { 
     long time = System.currentTimeMillis(); 
     Organism finalorg = iterate(); 
     System.out.println("TIME: " +(System.currentTimeMillis() - time)); 
     for(int i = 0; i < finalorg.DNA.length; ++i){ 
      System.out.println(finalorg.DNA[i]); 
     } 
     BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); 
     while(true) 

     System.out.println(finalorg.digitSum(Integer.parseInt(r.readLine()))); 
    } 
    public static Organism iterate(){ 
     while(true){ 
      if (firsttime){ 
       firsttime = false; 
       generation = new Organism[GENERATION]; 
       for (int i = 0; i < GENERATION; i++){ 
        generation[i] = Organism.parent(); //spawn first organisms 
       } 
      } 
      difference = getDifferences(generation); 
      int closest1 = Integer.MAX_VALUE; 
      int closest2 = Integer.MAX_VALUE; 
      Organism orgclosest1 = Organism.parent(); 
      Organism orgclosest2 = Organism.parent(); 

      System.out.println(average(difference)); 

      for (int i = 0; i < GENERATION; i++){ 

       if(Math.abs(difference[i]) <= RETURNTHRESHOLD && Math.abs(difference[i]) >= -RETURNTHRESHOLD){ 
        return generation[i]; 
       } 

       if(Math.abs(difference[i]) < closest1){ 
        orgclosest2 = orgclosest1; 
        orgclosest1 = generation[i]; 

        closest2 = closest1; 
        closest1 = Math.abs(difference[i]); 
       } 
       else if (Math.abs(difference[i]) < closest2 && Math.abs(difference[i]) != closest1){ 
        closest2 = Math.abs(difference[i]); 
        orgclosest2 = generation[i]; 
       } 
      } 
      //orgclosest1 = parent 1, etc 
      for(int i = 0; i < GENERATION; ++i) 
       generation[i] = Organism.child(orgclosest1, orgclosest2); 
     } 
    } 
    private static double average(int[] data) { 
     int sum = 0; 
     for (int d : data) sum += d; 
     return 1.0d * sum/data.length; 
    } 
    public static int[] getDifferences(Organism[] parents){ 
     int[] differencescore = new int[parents.length]; 
     for(int i = 0; i < parents.length; ++i){ 
      for(int x = 1; x < TEST; ++x){ 
       int sum = realSumDigits(x); 
       int orgSum = parents[i].digitSum(x); 
       differencescore[i] += orgSum - sum; 
      } 
     } 
     return differencescore; 
    } 
    private static int realSumDigits(int digits) { 
     int sum = 0; 
     while (digits > 0) 
     { 
      sum += digits % 10; 
      digits /= 10; 
     } 
     return sum; 
    } 
} 

Organism.java

public class Organism { 
    int[] DNA; //((i & d)/d) +... 

    public Organism(int[] DNA){ 
     this.DNA = DNA; 
    } 
    public int digitSum(int x){ 
     for (int i = 0; i < DNA.length; ++i){ 
      if (DNA[i] != 0) 
       x += (x & DNA[i])/DNA[i]; 
     } 
     return x; 
    } 

    public static Organism child(Organism p1, Organism p2){ 
     int[] DNA = new int[CodeEvolution.DNABITS]; 
     for (int i = 0; i < DNA.length; i++){ 
      DNA[i] = average(p1.DNA[i], p2.DNA[i]) + random(CodeEvolution.MUTATION); 
     } 
     return new Organism(DNA); 
    } 

    public static Organism parent(){ 
     int[] DNA = new int[CodeEvolution.DNABITS]; 
     for (int i = 0; i < DNA.length; i++){ 
      DNA[i] = random(CodeEvolution.PARENT) + (CodeEvolution.PARENT/2); 
     } 
     return new Organism(DNA); 
    } 
    private static int random(int mutation) { 
     return CodeEvolution.rand.nextInt(mutation) - (mutation/2); 
    } 
    private static int average(int i, int j) { 
     return (i + j)/2; 
    } 
} 

編輯: 也許我應該改變DNA基於方程找到每個生物體的digitsum?你會建議什麼?

回答

0

沒有「正確」的方法來做到這一點。我的建議是創建一個錦標賽選擇功能(您目前沒有看到),以匹配兩(2)個足夠好的父母創建下一個生物。這就是你的進化如何運作:)