Javaで遺伝的アルゴリズムを作成する際に問題があります。私はオンラインのGAコンテストで競合しています。私はインデックス0に毎回最良の結果を保存しようとしていますが、元のインデックスへの参照になります。私が残りのインデックスを進化させるとき、それが最良のメンバーの元のインデックスを進化させるなら、私はそれを失うことを意味します。Javaでの遺伝的アルゴリズムの問題
私は、オブジェクトデータをint配列に変換し、そこから新しいオブジェクトを作成するgetCloneメソッドでシミングを試みました。
個々のクラス:
class Individual {
public int[] angle;
public int[] thrust;
public double fitness;
public Individual(){
angle = new int[2];
thrust = new int[2];
for (int i = 0; i < 2; i++) {
this.angle[i] = ThreadLocalRandom.current().nextInt(0, 37) - 18;
this.thrust[i] = ThreadLocalRandom.current().nextInt(0, 202);
this.thrust[i] = ((this.thrust[i] == 201) ? 650 : this.thrust[i]);
}
this.fitness = Double.MIN_VALUE;
}
public Individual(int[][] genes, double f){
this.fitness = f;
angle = new int[2];
thrust = new int[2];
this.angle[0] = genes[0][0];
this.angle[1] = genes[0][1];
this.thrust[0] = genes[1][0];
this.thrust[1] = genes[1][1];
}
public Individual getClone() {
int[][] genes = new int[2][2];
genes[0][0] = (int)this.angle[0];
genes[0][1] = (int)this.angle[1];
genes[1][0] = (int)this.thrust[0];
genes[1][1] = (int)this.thrust[1];
return (new Individual(genes, this.fitness));
}
public Individual crossover(Individual other) {
int[][] genes = new int[2][2];
genes[0][0] = (int)((this.angle[0] + other.angle[0])/2);
genes[0][1] = (int)((this.angle[1] + other.angle[1])/2);
genes[1][0] = ((this.thrust[0] == 650 || other.thrust[0] == 650) ? 650: (int)((this.thrust[0] + other.thrust[0])/2));
genes[1][1] = ((this.thrust[1] == 650 || other.thrust[1] == 650) ? 650: (int)((this.thrust[1] + other.thrust[1])/2));
return (new Individual(genes, Double.MIN_VALUE));
}
public void mutate() {
for (int i = 0; i < 2; i++) {
if(ThreadLocalRandom.current().nextInt(0, 2)==1) {
this.angle[i] = ThreadLocalRandom.current().nextInt(0, 37) - 18;
}
if(ThreadLocalRandom.current().nextInt(0, 2)==1) {
this.thrust[i] = ThreadLocalRandom.current().nextInt(0, 202);
this.thrust[i] = ((this.thrust[i] == 201) ? 650 : this.thrust[i]);
}
}
}
人口クラス:SIMクラスから
class Population {
public Individual[] individuals;
public Population(int populationSize) {
individuals = new Individual[populationSize];
for (int i = 0; i < populationSize; i ++) {
individuals[i] = new Individual();
}
}
public void resetFitness() {
for (int i = 0; i < individuals.length; i++) {
individuals[i].fitness = Double.MIN_VALUE;
}
}
public void setIndividual(int i, Individual indiv) {
individuals[i] = indiv.getClone();
}
public Individual getIndividual(int i) {
return individuals[i].getClone();
}
public int size() {
return this.individuals.length;
}
public Individual getFittest() {
int fittest = 0;
// Loop through individuals to find fittest
for (int i = 0; i < individuals.length; i++) {
if (individuals[i].fitness > individuals[fittest].fitness) {
fittest = i;
}
}
return individuals[fittest].getClone();
}
}
必需:
class simGA {
private Population pop;
private final static int TSIZE = 5; //tournement size
public simGA (int poolsize) {
this.pop = new Population(poolsize);
}
public Individual search(int generations, int totalMoves) {
//this.pop.resetFitness();
for (int g = 0; g < generations; g++) {
for (int i = 0; i < this.pop.individuals.length; i++) {
this.pop.individuals[i].fitness = sim(this.pop.individuals[i],totalMoves);
}
System.err.print("Generation " + g + " ");
this.pop = evolvePopulation(this.pop);
}
return pop.getFittest();
}
private Population evolvePopulation(Population p) {
//save fittest
Population tempPop = new Population(p.individuals.length);
tempPop.setIndividual(0, p.getFittest().getClone());
System.err.print("Best move: " + tempPop.individuals[0].fitness);
System.err.println();
for (int i = 1; i < p.individuals.length; i++) {
Individual indiv1 = tournamentSelection(p);
Individual indiv2 = tournamentSelection(p);
Individual newIndiv = indiv1.crossover(indiv2);
newIndiv.mutate();
tempPop.setIndividual(i, newIndiv.getClone());
}
return tempPop;
}
// Select individuals for crossover
private Individual tournamentSelection(Population pop) {
// Create a tournament population
Population tournament = new Population(TSIZE);
// For each place in the tournament get a random individual
for (int i = 0; i < TSIZE; i++) {
int randomId = ThreadLocalRandom.current().nextInt(1, this.pop.individuals.length);
tournament.setIndividual(i, pop.getIndividual(randomId).getClone());
}
// Get the fittest
return tournament.getFittest().getClone();
}
private double sim(Individual s, int moves) {
return score; //score of simmed moves
}
どのように私は最高の個人が救われることを確認することができます、参照としてではない?最高のスコアを印刷するときにエラーが発生すると、スコアが失われ、悪いスコアリングが選択されることがあります。私はそれが必ずしもオブジェクトのクローンニングの問題ではないと思う、私はちょうどうまくシミュレートされているゲームオブジェクトを複製し、それぞれの実行をリセットすることができます。
私が言ったように、これはコンテスト用なので、サイト上でライブラリを使用することはできません。また、完全なコードを投稿していない理由は、シミュレータの複雑さです。ちょうど離れて与えられる。しかし、紙の上で動いたときの動きのために期待通りのスコアが戻ってくると言えば十分です。
NWSへの応答として、私はgetCloneメソッドがディープコピーを実行していると思いました。
遺伝的アルゴリズム上のwikiやその他の知識の横に使用リファレンス:http://www.theprojectspot.com/tutorial-post/creating-a-genetic-algorithm-for-beginners/3
私はインデックス0で個人をresimmingないことによってそれを固定しているが、これは問題に関連していない私のコードと他の問題があることを意味します。
これはディープコピーとシャローコピーの問題ではありませんか? – NWS
を保存するには、新しいオブジェクトを作成し、すべての属性値に格納する必要があります。いくつかのカスでは、私はこの新しいオブジェクトのコレクションを格納することを好む。 – bilelovitch