I use JGAP as part of my Crunch clustering tool. For my thesis writeup, I needed to describe the specific parameters to the genetic algorithm it used. This post details how JGAP starts up, and where to find the defaults, what they are and what the values actually mean. These values are probably specific to the version I’m looking at (3.62), although they haven’t changed in roughly 4 years at the time of writing.
The search parameters are contained in a
Configuration object. The configuration is initialised with various parameters and the type of chromosome to produce. The
Genotype represents the population, and exposes the GA component to the user (via the
Genotypes can be bootstrapped from a
Configuration via the
randomInitialGenotype method. This constructs the population (which uses
randomInitialChromosome to produce random individuals) and returns the initialised
evolve has three overloaded methods, the two that take arguments internally call the no-argument version.
IBreeders coordinate the evolution step, however they do not actually perform or store any of the genetic operators. These are kept in the
Configuration object’s m_geneticOperators field.
The default Breeder used is the
GABreeder. The following stages are applied to the population:
The fitness of each individual in the population is first calculated, using the bulk fitness function, or via
updateChromosomes if one isn’t provided.
Natural Selectors (Before Genetic Operators)
Each of the
NaturalSelectors registered for application before the genetic operator chain runs is run on the population. The default configuration does not set any of these selectors.
Each of the genetic operators registered in the configuration is run, one at a time, in order of addition to the Configuration. Implementation for this step appears in
BreederBase.applyGeneticOperators. The genetic operators implement an
operate method, which runs over the population. These may only add to the population, however; an operator should never modify an individual in the population. A
IChromosomes is passed as well as a
Population, although this is just a reference to the
Population‘s internal list.
DefaultConfiguration uses a Crossover operator, followed by a Mutation operator. Parameters to these are given at the end of this post.
The population is then re-evaluated, as it contains new individuals not present before the first round of selection.
Natural Selectors (After Genetic Operators)
Finally, the new population is produced by applying a
NaturalSelector to it. If the selector selects too few individuals, JGAP can optionally fill the remainder with random individuals – change
MinimumPopSizePercent to turn this on, but it’s off by default.
The Default JGAP Configuration
DefaultConfiguration sets up the following operator chain:
Rate: 35%, which translates to populationSize * 0.35 crossover operations per generation. Each crossover produces 2 individuals. Crossover point is random.
Desired Rate: 12. The rate for this one is a little different; mutation occurs if a random integer between 0 and the rate (12) is 0, thus it equates to a probability of 1/12. This operation is applied to each gene in each element of the population (excluding those produced by crossover), so the rough likelihood of a mutation being applied is (1/rate) * popSize * chromosomeSize. For each gene that is to be mutated, a copy of the whole
IChromosome that contains it is made, with the selected
Gene mutated via its
One selector is defined by default, which is the BestChromosomesSelector. This selector is given the following parameters:
Original Rate: 0.9. 90% of the population size allotted to this selector will actually be used. The selector is elitist, so this will return the top populationSize * 0.9 elements. The remaining 10% is filled by cloning the selected elements, one by one, in order of fitness until the population size reaches the limit.
Doublette Chromosomes Allowed? Yes. Doublettes are equivalent chromosomes (by
The configuration specifies that the pool of selectors will select 100% of the population size. However, the only selector is configured to produce only 90% of the population size each time.
keepPopulationSizeConstant is also set to true, which dictates that the population is trimmed to size at each iteration. Somewhat counter-intuitively, this does not cause the population size to be increased if it falls below the user supplied value; it doesn’t enforce a minimum, only a maximum
minimumPopSizePercent is set to zero, so random individuals will never be used to fill the population if it declines below the limit (won’t ever happen under these conditions).
So What is the Default?
The default configuration is an elitist ranking selector that clones the top 90% of the user-specified population size, repeating it to fill the rest. Crossover is random point with a rate of populationSize * 0.35. Mutation is random and applied at to 1 in 12 genes in the whole population (i.e. the rate is dictated by chromosome size * population size / 12).