📄 gpgenotype.java
字号:
GPPopulation newPopulation = new GPPopulation(oldPop, false);
if (m_fittestToAdd != null) {
newPopulation.addFittestProgram(m_fittestToAdd);
m_fittestToAdd = null;
}
float val;
RandomGenerator random = getGPConfiguration().getRandomGenerator();
GPConfiguration conf = getGPConfiguration();
// Determine how many new individuals will be added to the new generation.
// -----------------------------------------------------------------------
int popSize1 = (int) Math.round(popSize * (1 - conf.getNewChromsPercent()));
double crossProb = conf.getCrossoverProb()
/ (conf.getCrossoverProb() + conf.getReproductionProb());
int crossover = 0;
int reproduction = 0;
int creation = 0;
checkErroneousPop(getGPPopulation(), " (before evolution)", true);
final int maxTries = getGPConfiguration().getProgramCreationMaxtries();
// Do crossing over.
// -----------------
for (int i = 0; i < popSize1; i++) {
// Clear the stack for each GP program.
// ------------------------------------
getGPConfiguration().clearStack();
val = random.nextFloat();
// Note that if we only have one slot left to fill, we don't do
// crossover, but fall through to reproduction.
// ------------------------------------------------------------
if (i < popSize - 1 && val < crossProb) {
crossover++;
// Actually do the crossover here.
// -------------------------------
IGPProgram i1 = conf.getSelectionMethod().select(this);
IGPProgram i2 = conf.getSelectionMethod().select(this);
int tries = 0;
do {
try {
checkErroneousProg(i1,
" at start of evolution (index " + i + "/01)", false);
checkErroneousProg(i2,
" at start of evolution (index " + i + "/02)", false);
IGPProgram[] newIndividuals = conf.getCrossMethod().operate(i1,
i2);
newPopulation.setGPProgram(i, newIndividuals[0]);
newPopulation.setGPProgram(i + 1, newIndividuals[1]);
try {
checkErroneousProg(newIndividuals[0],
" at start of evolution (index " + i +
"/11)", false);
} catch (RuntimeException t) {
writeToFile(i1, i2, newIndividuals[0],
"Error in first X-over program");
throw t;
}
try {
checkErroneousProg(newIndividuals[1],
" at start of evolution (index " + i +
"/12)", false);
} catch (RuntimeException t) {
writeToFile(i1, i2, newIndividuals[1],
"Error in second X-over program");
throw t;
}
i++;
break;
} catch (IllegalStateException iex) {
tries++;
if ( (maxTries > 0 && tries >= maxTries) || tries > 40) {
if (!getGPConfiguration().isMaxNodeWarningPrinted()) {
LOGGER.error(
"Warning: Maximum number of nodes allowed may be too small");
getGPConfiguration().flagMaxNodeWarningPrinted();
}
// Try cloning a previously generated valid program.
// -------------------------------------------------
IGPProgram program = cloneProgram(getGPConfiguration().
getPrototypeProgram());
if (program != null) {
newPopulation.setGPProgram(i++, program);
program = cloneProgram(getGPConfiguration().
getPrototypeProgram());
newPopulation.setGPProgram(i, program);
break;
}
else {
throw new IllegalStateException(iex.getMessage());
}
}
}
} while (true)
;
}
else { //if (val < conf.getCrossoverProb() + conf.getReproductionProb()) {
// Reproduction only.
// ------------------
reproduction++;
newPopulation.setGPProgram(i, conf.getSelectionMethod().select(this));
}
}
// Add new random programs.
// ------------------------
for (int i = popSize1; i < popSize; i++) {
creation++;
// Randomly determine depth between minInitDepth and maxInitDepth.
// ---------------------------------------------------------------
int depth = conf.getMinInitDepth()
+ random.nextInt(conf.getMaxInitDepth() - conf.getMinInitDepth()
+ 1);
int tries = 0;
do {
try {
// Randomize grow option as growing produces a valid program
// more likely than the full mode.
// ---------------------------------------------------------
boolean grow;
if (i % 2 == 0 || random.nextInt(8) > 6) {
grow = true;
}
else {
grow = false;
}
/**@todo use program creator in case such is registered and returns
* a non-null program
*/
IGPProgram program = newPopulation.create(i, m_types, m_argTypes,
m_nodeSets, m_minDepths, m_maxDepths, depth, grow,
m_maxNodes, m_fullModeAllowed, tries);
newPopulation.setGPProgram(i, program);
checkErroneousProg(program,
" when adding a program, evolution (index " + i +
")", true);
LOGGER.debug("Added new GP program (depth "
+ depth
+ ", "
+ tries
+ " tries)");
break;
} catch (IllegalStateException iex) {
tries++;
/**@todo instead of re-using prototype, create a program anyway
* (ignoring the validator) in case it is the last try.
* Or even better: Make the validator return a defect rate!
*/
if ( (maxTries > 0 && tries > maxTries) || tries > 40) {
LOGGER.debug(
"Creating random GP program failed (depth "
+ depth
+ ", "
+ tries
+ " tries), will use prototype");
// Try cloning a previously generated valid program.
// -------------------------------------------------
IGPProgram program = cloneProgram(getGPConfiguration().
getPrototypeProgram());
if (program != null) {
// Cloning worked.
// ---------------
newPopulation.setGPProgram(i, program);
break;
}
else {
if (getGPConfiguration().getPrototypeProgram() == null) {
throw new IllegalStateException(
"Cloning: Prototype program was null");
}
else {
throw new IllegalStateException(
"Cloning of prototype program failed, " +
iex.getMessage());
}
}
}
}
} while (true)
;
}
LOGGER.debug("Did "
+ crossover + " x-overs, "
+ reproduction + " reproductions, "
+ creation + " creations");
// Now set the new population as the active one.
// ---------------------------------------------
setGPPopulation(newPopulation);
// Increase number of generation.
// ------------------------------
conf.incrementGenerationNr();
// Fire an event to indicate we've performed an evolution.
// -------------------------------------------------------
conf.getEventManager().fireGeneticEvent(
new GeneticEvent(GeneticEvent.GPGENOTYPE_EVOLVED_EVENT, this));
} catch (InvalidConfigurationException iex) {
// This should never happen.
// -------------------------
throw new IllegalStateException(iex.getMessage());
}
}
public GPPopulation getGPPopulation() {
return m_population;
}
/**
* @return the total fitness, that is the fitness over all chromosomes
*
* @author Klaus Meffert
* @since 3.0
*/
public double getTotalFitness() {
return m_totalFitness;
}
/**
* Default implementation of method to run GPGenotype as a thread.
*
* @author Klaus Meffert
* @since 3.0
*/
public void run() {
try {
while (!Thread.currentThread().interrupted()) {
evolve();
calcFitness();
// Pause between evolutions to avoid 100% CPU load.
// ------------------------------------------------
Thread.sleep(10);
}
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
/**
* Retrieves the GPProgram in the population with the highest fitness
* value.
*
* @return the GPProgram with the highest fitness value, or null if there
* are no programs in this Genotype
*
* @author Klaus Meffert
* @since 3.0
*/
public synchronized IGPProgram getFittestProgram() {
double fittest;
if (m_allTimeBest != null) {
fittest = m_allTimeBest.getFitnessValue();
}
else {
fittest = FitnessFunction.NO_FITNESS_VALUE;
}
IGPProgram fittestPop = getGPPopulation().determineFittestProgram();
if (fittestPop == null) {
return m_allTimeBest;
}
if (getGPConfiguration().getGPFitnessEvaluator().isFitter(fittest,
fittestPop.getFitnessValue())) {
return m_allTimeBest;
}
else {
// m_allTimeBest = fittestPop;/**@todo*/
return fittestPop;
}
}
/**
* Retrieves the GPProgram in the population with the highest fitness
* value. Only considers programs for which the fitness value has already
* been computed.
*
* @return the GPProgram with the highest fitness value, or null if there
* are no programs with known fitness value in this Genotype
*
* @author Klaus Meffert
* @since 3.2
*/
public synchronized IGPProgram getFittestProgramComputed() {
return getGPPopulation().determineFittestProgramComputed();
}
protected void setGPPopulation(GPPopulation a_pop) {
m_population = a_pop;
}
/**
* Sets the configuration to use with the Genetic Algorithm.
* @param a_configuration the configuration to use
*
* @author Klaus Meffert
* @since 3.0
*/
public void setGPConfiguration(GPConfiguration a_configuration) {
m_configuration = a_configuration;
}
/**
* Compares this entity against the specified object.
*
* @param a_other the object to compare against
* @return true: if the objects are the same, false otherwise
*
* @author Klaus Meffert
* @since 3.0
*/
public boolean equals(Object a_other) {
try {
return compareTo(a_other) == 0;
} catch (ClassCastException cex) {
return false;
}
}
/**
* Compares this Genotype against the specified object. The result is true
* if the argument is an instance of the Genotype class, has exactly the
* same number of programs as the given Genotype, and, for each
* GPProgram in this Genotype, there is an equal program in the
* given Genotype. The programs do not need to appear in the same order
* within the populations.
*
* @param a_other the object to compare against
* @return a negative number if this genotype is "less than" the given
* genotype, zero if they are equal to each other, and a positive number if
* this genotype is "greater than" the given genotype
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -