A concrete class which is a subclass of IPopulation
fills a number of important (and relatively obvious) roles in a VUWLGP run. Primarily, an instance of this class manages the memory of a population of programs and given a certain fitness environment can carry out an evolutionary search on that environment, as specified by its Config
object. In more detail, to carry out this beam search, this class is responsible for:
IPopulation::Evolve
).IPopulation::IteratePopulation = 0
, given the current fitnesses of the programs, to create a new population - the changed members of this population can then be evaluated with IPopulation::EvaluateFlaggedPrograms
.IPopulation
also defines IPopulation::SelectProgByFitness = 0
, which controls how a program is selected for an evolutionary operation.IPopulation
. Sub-classes can define their own. Each evolutionary operation should have the form: Program* Op() const
.SolutionExists
. This method returns true if there is a program with fitness <= config->epsilon
.IPopulation::Evolve
each of these steps will now be described in more detail. IPopulation::Evolve
and the overall evolutionary search are standard and also described in much more detail in, e.g., Koza 92, and so not covered here. Note also that the method Evolve
returns the number of generations used to find a solution, or, if no solution was found, one more than the maximum number of generations the population's config object allows is returned. This allows situations where no solution is found to be differentiated from situations where a solution is found in the last generation.
This method is abstract in IPopulation
and must be defined in a subclass which is used as the actual population.
When this method is called some (perhaps all) members of the population may be changed based on their fitness. This function can probably assume the fitness measures for each program are accurate, although if a program was flagged as having an inaccurate fitness an implementation could ignore it, update its fitness on the fly, etc - just as is appropriate for the search implemented.
Changes to the population are typically done by carrying out some evolutionary operators, perhaps selected from a WeightedCollection
of function pointers to the evolutionary operations created in IteratePopulation
. (This weighted collection of function pointers will be formalised and seperated out into functions in the next version of VUWLGP, to support further generalisatibility.) Generally, members of the population are then selected in some way from the population, deleted and their positions in the internal representation of the population taken by the pointers returned by the evolutionary operations. It is suggested that users of VUWLGP who are developing a new subclass of IPopulation
examine the existing subclasses (this examination of the source code is a generally good approach - it has been nicely commented for your reading pleasure!)
This method should return a pointer to a program in this population, selected according to its fitness. As with IteratePopulation
this method is abstract and is the second of the two methods which must be defined in any implementation of IPopulation
. It is suggested that users of VUWLGP who are developing a new subclass of IPopulation
examine the existing subclasses.
IPopulation
defines 7 basic evolutionary operations. All evolutionary operations are members of a population class and typically use SelectProgByFitness
to select however many programs are needed for the operation. They always have the form Program* Op() const
.
As the const pointer returned by SelectProgByFitness
makes clear the evolutionary operations should not modify the programs they select themselves. Instead they should return a pointer to a new program, and rely on the population class to manage both the memory of the new program and also the old program whose place the new one is taking.
This method is mentioned here because it should be noted that the current implementation of VUWLGP is structured in such a way that a lower fitness is assumed to be better - this assumption is made explicit in this method, in IPopulation::SortFittestFirst
and IPopulation::SortFittestLast
and possibly in other parts of the code as well, although many other areas, e.g. IFitnessMeasure::UpdateError = 0
are abstract. Further generalisation so that a higher fitness could be considered better is tentatively planned for some future version of VUWLGP.
Christopher Fogelberg
fogelbchri@mcs.vuw.ac.nz or cgf.unimail@syntilect.com