📄 gpgenotype.java
字号:
* @param a_conf the configuration to use
* @param a_types the type of each chromosome, the length is the number of
* chromosomes
* @param a_argTypes the types of the arguments to each chromosome, must be an
* array of arrays, the first dimension of which is the number of chromosomes
* and the second dimension of which is the number of arguments to the
* chromosome
* @param a_nodeSets the nodes which are allowed to be used by each
* chromosome, must be an array of arrays, the first dimension of which is the
* number of chromosomes and the second dimension of which is the number of
* nodes. Note that it is not necessary to include the arguments of a
* chromosome as terminals in the chromosome's node set. This is done
* automatically
* @param a_minDepths array of minimum depths to use: for each chromosome
* one entry
* @param a_maxDepths array of maximum depths to use: for each chromosome
* one entry
* @param a_maxNodes reserve space for a_maxNodes number of nodes
* @param a_fullModeAllowed array of boolean values. For each chromosome there
* is one value indicating whether the full mode for creating chromosome
* generations during evolution is allowed (true) or not (false)
* @param a_verboseOutput true: output status information to console
* @param a_popCreator mechanism fior creating the population
*
* @return GPGenotype
*
* @throws InvalidConfigurationException
*
* @author Klaus Meffert
* @since 3.2.2
*/
public static GPGenotype randomInitialGenotype(final GPConfiguration a_conf,
Class[] a_types, Class[][] a_argTypes, CommandGene[][] a_nodeSets,
int[] a_minDepths, int[] a_maxDepths, int a_maxNodes,
boolean[] a_fullModeAllowed, boolean a_verboseOutput,
IPopulationCreator a_popCreator)
throws InvalidConfigurationException {
// Check preconditions.
// --------------------
if (a_argTypes.length != a_fullModeAllowed.length
|| (a_minDepths != null && a_argTypes.length != a_minDepths.length)
|| (a_maxDepths != null && a_argTypes.length != a_maxDepths.length)
|| a_argTypes.length != a_types.length) {
throw new IllegalArgumentException("a_argTypes must have same length"
+
" as a_types, a_minDepths, a_maxDepths and a_fullModeAllowed");
}
if (a_conf.getPopulationSize() < 1) {
throw new IllegalArgumentException("Set the population size in the"
+ " configuration!");
}
// Clean up memory.
// ----------------
System.gc();
if (a_verboseOutput) {
LOGGER.info("Creating initial population");
LOGGER.info("Mem free: "
+ SystemKit.niceMemory(SystemKit.getTotalMemoryMB()) + " MB");
}
// Create initial population.
// --------------------------
GPPopulation pop = new GPPopulation(a_conf, a_conf.getPopulationSize());
try {
a_popCreator.initialize(pop, a_types, a_argTypes, a_nodeSets, a_minDepths,
a_maxDepths, a_maxNodes, a_fullModeAllowed);
} catch (Exception ex) {
throw new InvalidConfigurationException(ex);
}
System.gc();
if (a_verboseOutput) {
LOGGER.info("Mem free after creating population: "
+ SystemKit.niceMemory(SystemKit.getTotalMemoryMB()) + " MB");
}
checkErroneousPop(pop, " after creating population/2");
GPGenotype gp = new GPGenotype(a_conf, pop, a_types, a_argTypes, a_nodeSets,
a_minDepths, a_maxDepths, a_maxNodes);
gp.m_fullModeAllowed = a_fullModeAllowed;
// Publish GP variables to configuration to make them accessible globally.
// -----------------------------------------------------------------------
Iterator it = gp.m_variables.keySet().iterator();
while (it.hasNext()) {
/**@todo optimize access to map*/
String varName = (String) it.next();
Variable var = (Variable) gp.m_variables.get(varName);
a_conf.putVariable(var);
}
gp.checkErroneousPop(gp.getGPPopulation(), " after creating population/2");
return gp;
}
public GPConfiguration getGPConfiguration() {
return m_configuration;
}
/**
* @return the static configuration to use with Genetic Programming
*
* @author Klaus Meffert
* @since 3.2
*/
public static GPConfiguration getStaticGPConfiguration() {
return m_staticConfiguration;
}
/**
* Sets the static configuration to use with the Genetic Programming.
*
* @param a_configuration the static configuration to use
*
* @author Klaus Meffert
* @since 3.2
*/
public static void setStaticGPConfiguration(GPConfiguration a_configuration) {
m_staticConfiguration = a_configuration;
}
static class GPFitnessComparator
implements Comparator {
public int compare(Object o1, Object o2) {
if (! (o1 instanceof IGPProgram) ||
! (o2 instanceof IGPProgram))
throw new ClassCastException(
"FitnessComparator must operate on IGPProgram instances");
double f1 = ( (IGPProgram) o1).getFitnessValue();
double f2 = ( (IGPProgram) o2).getFitnessValue();
if (f1 > f2) {
return 1;
}
else if (Math.abs(f1 - f2) < 0.000001) {
return 0;
}
else {
return -1;
}
}
}
/**
* Evolves the population n times.
*
* @param a_evolutions number of evolution
*
* @author Klaus Meffert
* @since 3.0
*/
public void evolve(int a_evolutions) {
int offset = getGPConfiguration().getGenerationNr();
int evolutions;
if (a_evolutions < 0) {
evolutions = Integer.MAX_VALUE;
}
else {
evolutions = a_evolutions;
}
// getGPPopulation().sort(new GPFitnessComparator());
for (int i = 0; i < evolutions; i++) {
// if (m_bestFitness < 0.000001) {
// // Optimal solution found, quit.
// // -----------------------------
// return;
// }
if (m_verbose) {
if (i % 25 == 0) {
String freeMB = SystemKit.niceMemory(SystemKit.getFreeMemoryMB());
LOGGER.info("Evolving generation "
+ (i + offset)
+ ", memory free: "
+ freeMB
+ " MB");
}
}
evolve();
calcFitness();
}
}
/**
* Calculates the fitness value of all programs, of the best solution as well
* as the total fitness (sum of all fitness values).
*
* @author Klaus Meffert
* @since 3.0
*/
public void calcFitness() {
double totalFitness = 0.0d;
GPPopulation pop = getGPPopulation();
IGPProgram best = null;
IGPFitnessEvaluator evaluator = getGPConfiguration().getGPFitnessEvaluator();
m_bestFitness = FitnessFunction.NO_FITNESS_VALUE;
boolean bestPreserved = false;
for (int i = 0; i < pop.size() && pop.getGPProgram(i) != null; i++) {
IGPProgram program = pop.getGPProgram(i);
/**@todo get information from fitness function how calculation happened.
* In case of Robocode: return the robot competed against, in case the
* -enemies option was used without -battleAll
*/
double fitness;
try {
fitness = program.getFitnessValue();
} catch (IllegalStateException iex) {
fitness = Double.NaN;
}
// Don't acceppt Infinity or NaN as a result.
// ------------------------------------------
if (Double.isInfinite(fitness) || Double.isNaN(fitness)) {
continue;
}
if (best == null || evaluator.isFitter(fitness, m_bestFitness)) {
best = program;
m_bestFitness = fitness;
if (!bestPreserved && m_allTimeBest != null) {
if (best.toStringNorm(0).equals(m_allTimeBest.toStringNorm(0))) {
bestPreserved = true;
}
}
}
totalFitness += fitness;
}
m_totalFitness = totalFitness;
best = pop.determineFittestProgram();
if (best != null) {
m_bestFitness = best.getFitnessValue();
/**@todo do something similar here as with Genotype.preserveFittestChromosome*/
if (m_allTimeBest == null
|| evaluator.isFitter(m_bestFitness, m_allTimeBestFitness)) {
pop.setChanged(true);
try {
ICloneHandler cloner = getGPConfiguration().getJGAPFactory().
getCloneHandlerFor(best, null);
if (cloner == null) {
m_allTimeBest = best;
if (!m_cloneWarningGPProgramShown) {
LOGGER.info("Warning: cannot clone instance of "
+ best.getClass());
m_cloneWarningGPProgramShown = true;
}
}
else {
m_allTimeBest = (IGPProgram) cloner.perform(best, null, null);
}
} catch (Exception ex) {
m_allTimeBest = best;
ex.printStackTrace();
}
m_allTimeBestFitness = m_bestFitness;
// Fire an event to indicate a new best solution.
// ----------------------------------------------
/**@todo introduce global value object to be passed to the listener*/
try {
getGPConfiguration().getEventManager().fireGeneticEvent(
new GeneticEvent(GeneticEvent.GPGENOTYPE_NEW_BEST_SOLUTION, this));
} catch (IllegalArgumentException iex) {
/**@todo should not happen but does with ensureUniqueness(..)*/
}
if (m_verbose) {
// Output the new best solution found.
// -----------------------------------
outputSolution(m_allTimeBest);
}
}
}
if (!bestPreserved && m_allTimeBest != null) {
addFittestProgram(m_allTimeBest);
}
}
/**
* @return the all-time best solution found
*
* @author Klaus Meffert
* @since 3.0
*/
public IGPProgram getAllTimeBest() {
return m_allTimeBest;
}
/**
* Outputs the best solution until now.
*
* @param a_best the fittest ProgramChromosome
*
* @author Klaus Meffert
* @since 3.0
*/
public void outputSolution(IGPProgram a_best) {
if (a_best == null) {
LOGGER.debug("No best solution (null)");
return;
}
double bestValue = a_best.getFitnessValue();
if (Double.isInfinite(bestValue)) {
LOGGER.debug("No best solution (infinite)");
return;
}
LOGGER.info("Best solution fitness: " +
NumberKit.niceDecimalNumber(bestValue, 2));
LOGGER.info("Best solution: " + a_best.toStringNorm(0));
String depths = "";
int size = a_best.size();
for (int i = 0; i < size; i++) {
if (i > 0) {
depths += " / ";
}
depths += a_best.getChromosome(i).getDepth(0);
}
if (size == 1) {
LOGGER.info("Depth of chrom: " + depths);
}
else {
LOGGER.info("Depths of chroms: " + depths);
}
}
/**
* Evolve the population by one generation. Probabilistically reproduces
* and crosses individuals into a new population which then overwrites the
* original population.
*
* @author Klaus Meffert
* @since 3.0
*/
public void evolve() {
try {
int popSize = getGPConfiguration().getPopulationSize();
GPPopulation oldPop = getGPPopulation();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -