package jcgp.backend.population;
import java.util.Arrays;
import java.util.Collections;
import jcgp.backend.modules.problem.BestFitness;
import jcgp.backend.resources.Resources;
/**
* This class primarily holds a collection of chromosomes. In addition,
* it provides a few utility methods for manipulating and copying
* chromosomes, useful for evolutionary strategies.
*
* {@code copyChromosome()} is used to create copies of chromosomes,
* though it is also possible to create a new instance of population
* directly from a seed chromosome using the right constructor.
*
* For convenience, a random chromosome can be retrieved using
* {@code getRandomChromosome()}, which is guaranteed to use the
* experiment's specified seed. If an entirely random population
* is needed, {@code reinitialise()} should be used to randomise
* all chromosomes without creating a new instance of {@code Population}.
*
*
* @author Eduardo Pedroni
*
*/
public class Population {
private final Chromosome[] chromosomes;
private final Resources resources;
/**
* Initialise a random population according to the parameters specified
* in the resources.
*
* @param resources the experiment's resources.
*/
public Population(Resources resources) {
this.resources = resources;
chromosomes = new Chromosome[resources.populationSize()];
for (int c = 0; c < chromosomes.length; c++) {
chromosomes[c] = new Chromosome(resources);
}
}
/**
* Initialise a population of copies of the given chromosome.
*
* @param parent the chromosome to use as a model.
* @param resources a reference to the experiment's resources.
*/
public Population(Chromosome parent, Resources resources) {
this.resources = resources;
chromosomes = new Chromosome[resources.populationSize()];
for (int c = 0; c < chromosomes.length; c++) {
chromosomes[c] = new Chromosome(parent);
}
}
/**
* Returns the indexed chromosome.
*
* @param index the chromosome to return.
* @return the indexed chromosome.
*/
public Chromosome get(int index) {
return chromosomes[index];
}
/**
* @return a random chromosome from this population.
*/
public Chromosome getRandomChromosome() {
return chromosomes[resources.getRandomInt(chromosomes.length)];
}
/**
* Copy a chromosome into a different position.
* After this returns, the target chromosome has
* identical connections and functions to the source
* one, though they are separate instances.
*
* This method does nothing if source == target.
*
* @param source the chromosome to copy from.
* @param target the chromosome to copy to.
*/
public void copyChromosome(int source, int target) {
if (source != target) {
chromosomes[target].copyGenes(chromosomes[source]);
}
}
/**
* Loop through all chromosomes and randomise all connections
* and functions.
*/
public void reinitialise() {
for (int c = 0; c < chromosomes.length; c++) {
chromosomes[c].reinitialiseConnections();
}
}
/**
* Sorts the population in ascending order of fitness quality.
* What this means is that the best fitness chromosome will be
* in the last position, even though it might have the lowest
* fitness value. Fitness orientation as specified in the resources
* is respected.
*/
public void sort() {
if (resources.fitnessOrientation() == BestFitness.HIGH) {
Arrays.sort(chromosomes);
} else {
Arrays.sort(chromosomes, Collections.reverseOrder());
}
}
}