/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.cirqwizard.generation.optimizer;
import org.cirqwizard.geom.Point;
import org.cirqwizard.settings.ApplicationConstants;
import java.util.Random;
public class Phenotype
{
private int[] genes;
private Double fitness = null;
private static double MOTION_PENALTY = 2000;
public Phenotype(int[] genes)
{
this.genes = genes;
}
public double calculateFitness(Environment env)
{
if (fitness != null)
return fitness;
Point currentLocation = new Point(0, 0);
fitness = 0.0;
for (int i : genes)
{
Chain chain = env.getChains().get(i);
if (currentLocation.distanceTo(chain.getStart()) > ApplicationConstants.ROUNDING)
{
fitness += currentLocation.distanceTo(chain.getStart());
fitness += MOTION_PENALTY;
}
currentLocation = chain.getEnd();
}
return fitness;
}
public int[] getGenes()
{
return genes;
}
public Phenotype crossOver(Phenotype partner)
{
Random random = new Random();
int firstIndex = random.nextInt(genes.length);
int lastIndex = random.nextInt(genes.length);
int[] childGenes = new int[genes.length];
if (lastIndex < firstIndex)
lastIndex += genes.length;
int counter = 0;
boolean[] copied = new boolean[genes.length];
for (int i = firstIndex; i < lastIndex; i++)
{
int g = genes[i % genes.length];
childGenes[counter++] = g;
copied[g] = true;
}
for (int i = 0; i < partner.genes.length; i++)
{
if (!copied[partner.genes[i]])
childGenes[counter++] = partner.genes[i];
}
return new Phenotype(childGenes);
}
public void mutate()
{
Random random = new Random();
int genesCount = random.nextInt(genes.length / 2);
for (int i = 0; i < genesCount; i++)
{
int gene1 = random.nextInt(genes.length);
int gene2 = random.nextInt(genes.length);
int g = genes[gene1];
genes[gene1] = genes[gene2];
genes[gene2] = g;
}
}
}