こんにちは、私は遺伝的アルゴリズムを実装するプログラムの全体的な効率を高めることについていくつかのアドバイスを得ることができるかと思っていました。はい、これは課題の質問ですが、私はすでに自分で課題を完了しており、それをより適切に実行する方法を探しています。問題の説明
現時点で私のプログラムは、構成要素のタイプhまたはpで構成される特定のチェーンを読み取ります(例hphpphhphpphphhpphph)HおよびPごとにランダムな移動(上、下、左、右)を生成し、その移動をarrayListに追加します「Chromosome」オブジェクトに含まれています。開始時に、プログラムは10,000の染色体に対して19の移動を生成しています
SecureRandom sec = new SecureRandom();
byte[] sbuf = sec.generateSeed(8);
ByteBuffer bb = ByteBuffer.wrap(sbuf);
Random numberGen = new Random(bb.getLong());
int numberMoves = chromosoneData.length();
moveList = new ArrayList(numberMoves);
for (int a = 0; a < numberMoves; a++) {
int randomMove = numberGen.nextInt(4);
char typeChro = chromosoneData.charAt(a);
if (randomMove == 0) {
moveList.add(Move.Down);
} else if (randomMove == 1) {
moveList.add(Move.Up);
} else if (randomMove == 2) {
moveList.add(Move.Left);
} else if (randomMove == 3) {
moveList.add(Move.Right);
}
}
この後、人口から交雑までの染色体の選択が行われます。私のクロスオーバー機能は、最初の染色体を人口の最も適した20%からランダムに選択し、もう1つを上位20%の外側からランダムに選択します。次に、選択された染色体が交差され、突然変異関数が呼び出されます。私が最もヒットしている領域は、各染色体の適合度を計算することだと思います。現在、私のフィットネス関数はグリッドとして機能する2D配列を作成し、上記の関数で生成されたムーブリストから順番にムーブを配置し、配列をループしてフィットネス計算を行います。(IEが見つかり、場所[2,1]のHはコード[1,1] [3,1] [2,0]または[2,2]もHであり、Hが見つかった場合は、ボンドが見つかりました)
計算が完了すると、最小適合の染色体が母集団から削除され、新しい染色体が追加されて、染色体の配列リストがソートされます。ターゲット溶液が見つかるまですすぎ、繰り返す
皆さんが私のコードをもっと見たいので、助けを求める前に実際に作業をしたことを証明したい場合は、私に知らせてください(他の学生が私のものをパスタをコピーできないので、あまり投稿しないでください)
コメントで示唆されているように、私は自分のアプリケーションでプロファイラーを実行し(これまでに使用したことがなく、CSの1年生のみ)、問題が発生している場所についての最初の推測はやや不正確でした。プロファイラーが私に言っていることから、大きなホットスポットは次のようです:
1)新しい染色体を集団内の他の染色体と比較して、その位置を決定する場合。私はComparableを実装してこれを行っています。
public int compareTo(Chromosome other) {
if(this.fitness >= other.fitness)
return 1;
if(this.fitness ==other.fitness )
return 0;
else
return -1;
}
2)説明されている他の問題領域は私の実際の進化関数にあり、CPU時間の約40%を消費しています。以下の上記のメソッドのコードサンプル
double topPercentile = highestValue;
topPercentile = topPercentile * .20;
topPercentile = Math.ceil(topPercentile);
randomOne = numberGen.nextInt((int) topPercentile);
//Lower Bount for random two so it comes from outside of top 20%
int randomTwo = numberGen.nextInt(highestValue - (int) topPercentile);
randomTwo = randomTwo + 25;
//System.out.println("Selecting First: " + randomOne + " Selecting Second: " + randomTwo);
Chromosome firstChrom = (Chromosome) populationList.get(randomOne);
Chromosome secondChrom = (Chromosome) populationList.get(randomTwo);
//System.out.println("Selected 2 Chromosones Crossing Over");
Chromosome resultantChromosome = firstChrom.crossOver(secondChrom);
populationList.add(resultantChromosome);
Collections.sort(populationList);
populationList.remove(highestValue);
Chromosome bestResult = (Chromosome) populationList.get(0);
3)もう1つの主要なパフォーマンスヒットは、ポストの最初のコードサンプルによって実行される初期人口シードです。
人口を繰り返しソートする代わりに、すでにソートされたコンテンツを維持するコレクションを使用します。(例:TreeSet)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加