2016-10-06 22 views
2

私はJavaを使って簡単な遺伝的アルゴリズム(GA)を実装しています。私のGAの手順は、基本的にバイナリエンコーディング、トーナメント選択、シングルポイントクロスオーバ、ビットワイズの変換です。集団の各個体は、2値遺伝子および適合値からなるクラスによって表される。 Iは、GAの単一点交叉部に問題に直面してきたように以下Javaの遺伝的アルゴリズムシングルポイントクロスオーバーメカニズムのための助けが必要

public class Individual { 
    int gene[]; 
    int fitness; 

    public Individual(int n){ 
     this.gene = new int[n]; 
    } 
} 

コードは、ビット単位の変異部分を含みません。私がシングルポイントクロスオーバーアルゴリズムを実装した方法は、ランダムに2つの連続する個々の配列要素のポイントを見つけて、それらのテールを入れ替えることです。その後、尾部のスワッピングは、個々のペアごとに繰り返されます。また、printGenome()メソッドを作成して、比較するすべての配列を出力し、結果として得られた配列をクロスオーバー処理が正しくスワップされないようにしました。私は、私のシングルポイントクロスオーバーアルゴリズムを別々にテストしました。しかし、私がここで以下のコードで実行しようとしたとき、クロスオーバは単に機能しません。トーナメントセレクションアルゴリズムに何か問題があるので、私はそれが分かりますか?それとも別の何か(愚かな間違い)ですか?私はそれに修正を加えましたが、それでもエラーを特定できませんでした。

提供されたヘルプと情報に感謝します。 :)

public class GeneticAlgorithm { 

    public static void main(String[] args) { 
     int p = 10; 
     int n = 10; 
     Individual population[]; 

     //create new population 
     population = new Individual[p]; 

     for (int i = 0; i < p; i++) { 
      population[i] = new Individual(n); 
     } 

     //fills individual's gene with binary randomly 
     for (int i = 0; i < p; i++) { 
      for (int j = 0; j < n; j++) { 
       population[i].gene[j] = (Math.random() < 0.5) ? 0 : 1; 
      } 
      population[i].fitness = 0; 
     } 

     //evaluate each individual 
     for (int i = 0; i < p; i++) { 
      for (int j = 0; j < n; j++) { 
       if (population[i].gene[j] == 1) { 
        population[i].fitness++; 
       } 
      } 
     } 

     //total fitness check 
     System.out.println("Total fitness check #1 before tournament selection: " + getTotalFitness(population, p)); 
     System.out.println("Mean fitness check #1 before tournament selection: " + getMeanFitness(population, p)); 
     System.out.println(""); 

     //tournament selection 
     Individual offspring[] = new Individual[p]; 

     for (int i = 0; i < p; i++) { 
      offspring[i] = new Individual(n); 
     } 

     int parent1, parent2; 
     Random rand = new Random(); 
     for (int i = 0; i < p; i++) { 
      parent1 = rand.nextInt(p); //randomly choose parent 
      parent2 = rand.nextInt(p); //randomly choose parent 

      if (population[parent1].fitness >= population[parent2].fitness) { 
       offspring[i] = population[parent1]; 
      } else { 
       offspring[i] = population[parent2]; 
      } 
     } 

     //total fitness check 
     System.out.println("Total fitness check #2 after tournament selection: " + getTotalFitness(offspring, p)); 
     System.out.println("Mean fitness check #2 after tournament selection: " + getMeanFitness(offspring, p)); 
     System.out.println(""); 

     //genome check 
     System.out.println("Before Crossover: "); 
     printGenome(offspring, p, n); 

     //crossover 
     for (int i = 0; i < p; i = i + 2) { 
      int splitPoint = rand.nextInt(n); 
      for (int j = splitPoint; j < n; j++) { 
       int temp = offspring[i].gene[j]; 
       offspring[i].gene[j] = offspring[i + 1].gene[j]; 
       offspring[i + 1].gene[j] = temp; 
      } 
     } 

     //genome check 
     System.out.println("After Crossover:"); 
     printGenome(offspring, p, n); 

     //evaluate each individual by counting the number of 1s after crossover 
     for (int i = 0; i < p; i++) { 
      offspring[i].fitness = 0; 
      for (int j = 0; j < n; j++) { 
       if (offspring[i].gene[j] == 1) { 
        offspring[i].fitness++; 
       } 
      } 
     } 

     //total fitness check 
     System.out.println("Total fitness check #3 after crossover: " + getTotalFitness(offspring, p)); 
     System.out.println("Mean fitness check #3 after crossover: " + getMeanFitness(offspring, p)); 
    } 

    public static void printGenome(Individual pop[], int p, int n) { 
     for (int i = 0; i < p; i++) { 
      for (int j = 0; j < n; j++) { 
       System.out.print(pop[i].gene[j]); 
      } 
      System.out.println(""); 
     } 
    } 

    public static int getTotalFitness(Individual pop[], int p) { 
     int totalFitness = 0; 
     for (int i = 0; i < p; i++) { 
      totalFitness = totalFitness + pop[i].fitness; 
     } 
     return totalFitness; 
    } 

    public static double getMeanFitness(Individual pop[], int p) { 
     double meanFitness = getTotalFitness(pop, p)/(double) p; 
     return meanFitness; 
    } 

} 

答えて

0

問題はあなたの選択にあなたが言うとき、個人を複製(ほとんどの場合)している、ということである:

子孫[I] =人口[親1]

あなたは実際に母集団[親1]への参照を子孫[i]に格納しています。結果として、子孫配列に同じ参照が複数回含まれることがあります。したがって、同じオブジェクトが複数のパートナーと複数回クロスオーバーに参加します。

解決策として、同じオブジェクトへの参照の代わりに複製を格納することができます。個別に追加します。

public Individual clone(){ 
     Individual clone = new Individual(gene.length); 
     clone.gene = gene.clone(); 
     return clone; 
    } 

そして、あなたの選択では()(追加.cloneに注意してください):

for (int i = 0; i < p; i++) { 
     parent1 = rand.nextInt(p); //randomly choose parent 
     parent2 = rand.nextInt(p); //randomly choose parent 

     if (population[parent1].fitness >= population[parent2].fitness) { 
      offspring[i] = population[parent1].clone(); 
     } else { 
      offspring[i] = population[parent2].clone(); 
     } 
    } 

この方法を子孫内のすべての要素は、ゲノムが同じであっても、異なるオブジェクトであります。

これはJavaの部分を解決します。 GA理論に関して、私はいくつかのことを願っています。例えば、あなたのフィットネス測定値はちょうどプレースホルダです。

+0

私はこれを私のJavaコードではっきりとやっていますが、私はインデックス0でエリート個人を失い続けています。http://stackoverflow.com/questions/41340615/genetic-algorithm-in-java-problems –

関連する問題