2017-07-11 15 views
0

無限の猿の定理(https://en.wikipedia.org/wiki/Infinite_monkey_theorem)のようなものをシミュレートするために、ランダムな文字の集団を生成し、最終的には入力された文字列に着地するJavaプログラムを作成しようとしています。私が抱えている問題は、私がそれをテストしているので、開始人口のすべてが0のフィットネスレベルを持つので、何も自然選択プロセス中に交配プールに追加されません。ここにプロジェクトが伴うことがあります。遺伝的アルゴリズムフィットネススコアの問題

ターゲット:文字列 "こんにちは"

突然変異率: 0.01

人口最大: 100 DNAは、各遺伝子についてのchar []配列を含むオブジェクト。ここで

フィットネスを計算するための私の関数である。

public void calcFitness(String target){ 
     double score = 0.0; 
     for(int i = 0; i < this.genes.length; i++){ 
      if(this.genes[i] == target.charAt(i)){ 
       score++; 
      } 
     } 
     this.fitness = score/this.genes.length; 
    } 

私は遺伝的プログラミングに新しい、私が間違っているのかわからないです、どんな手助けがいただければ幸いと遺伝的プログラミングについてのヒントや洞察力も希望感謝する。

EDIT

ここで選択プロセスのためのコードです:

public void naturalSelection(){ 
     ArrayList<DNA> selection = new ArrayList<>(); 
     Random rand = new Random(); 
     String child = ""; 
     DNA[] newPop = new DNA[popMax]; 
     for(int i = 0; i < population.length; i++){ 
      for(int j = 0; j < population[i].getFitness(); j++){ 
       selection.add(population[i]); 
      } 
     } 
     for(int i = 0; i < selection.size(); i++){ 
      int parentSelect = rand.nextInt(selection.size()); 
      DNA parent1 = selection.get(parentSelect); 
      child = parent1.split(true); 
      parentSelect = rand.nextInt(selection.size()); 
      DNA parent2 = selection.get(parentSelect); 
      child += parent2.split(false); 
      newPop[i] = new DNA(child); 
     } 
     double mutation = rand.nextDouble(); 
     if(mutation < this.mutationRate){ 
      this.population = swapMutation(newPop); 
      calcFittest(); 
     } 
     else{ 
      this.population = newPop; 
      calcFittest(); 
     } 
    } 

変異が発生した場合、スワップ変異は、2つのランダムな文字を入れ替えます。

+0

このコードは問題ではないようです。 – Daedric

+0

問題の理解に問題があります。 '' Hello''が 'genes'に存在するかどうか確認しようとしていますか? – 17slim

+0

再現の確率は、フィットネススコアに比例する必要があります。また、あなたの場合は、他の個人の適応度に比例します。すべてがゼロ点を持っている場合は、すべてが同じ再現の可能性があります。しかし、より高いスコアの個人ははるかに高い可能性があります。あなたの問題はフィットネスのスコアを計算することではなく、それがどのように再現する個人を選択するのに使われているかのようです。 – hatchet

答えて

1

候補からターゲット文字列までの距離を測定するフィットネス機能を使用することをお勧めします。最大化するのではなく、全体的なフィットネスを最小限に抑えます。それははるかに優れた各候補者を区別しますので、これはより良い動作するはず

public void calcFitness(String target){ 
    double score = 0.0; 
    for(int i = 0; i < this.genes.length; i++){ 
     score += Math.abs((int)this.genes[i] - (int)target.charAt(i)); 
    } 
    this.fitness = score/this.genes.length; 
} 

:これを行うには

。あなたが使用しているランダムな文字列ジェネレータを見ることなく、それは言うことは難しいですが、可能性のある候補者の数は天文学的であり、いずれかがあなたのフィットネス機能で単一点を得ている可能性が非常に低い可能性があります。

あなたのコードは遺伝的プログラミングではなく遺伝的アルゴリズムの一部である可能性があります。

選択を改善したい場合は、簡単にプログラムできるテクニックとしてお勧めします。トーナメントの選択 - 人口から無作為の個体を選び、n個体から最良の個体を選択します。これにより、より良い候補者が他の個人よりも選択される可能性が高くなり、母集団内のすべての個人の適応度を計算する必要がないというボーナスが追加されます。

+0

はい、それは遺伝的アルゴリズムの一部です。遺伝的プログラミングの代わりに、これは私がランダムな文字ジェネレータに使用しているものです。 プライベートchar getChar(){ ランダムrand = newランダム(); char c =(char)((char)rand.nextInt(26)+ 'a'); char C =(char)((char)rand.nextInt(26)+ 'A'); if(rand.nextInt()%2 == 0){ return c; } else { return C; } } –

+0

自然選択コードを表示するために自分の投稿を編集しました。 –

0

私は無限の猿定理のためのGAを完成しました。 https://github.com/Willtl/infinite_monkey_theorem

これはC++でありますが、Javaで同じことをするのは難しくありません。 Eclipse CPPを使用してプロジェクトを開くことができます。

void Individual::calculateFitness(vector<char> chromosomePlate) { 
fitness = 0; 

for (int i = 0; i < chromosome.size(); i++) { 
    int gene = (int) chromosome[i]; 
    int genePlate = (int) chromosomePlate[i]; 
    if (gene == genePlate && gene != 32) { 
      fitness++; 
    } 
} 

まず入力を読み込むと、小文字になります。次に、ランダム化と比較を簡単にするために、私はASCIIを使用しています。だから私は小文字だけを考えているので、私のキャラクターの範囲は97から122になります。また、私は染色体上のスペースを保ちますが、フィットネス機能ではそれを無視します(32)。

あなたがここに投稿する必要があるものは何でもお手伝いします。

関連する問題