[0, 1, 2, 3, 4]
Quick Start
Introduction
Let’s assume we are trying to solve a problem where we want to generate N integers where their values are equal to their index.
For instance, for N = 5, we would want to generate the following list of integers:
We will solve this problem by generating an entire population of random lists of integers and evolving them towards our expected solution.
So let’s start by defining the constraints of our problem:
final int numEntries = 10; (1)
final int minValue = 0; (2)
final int maxValue = 20; (3)
1 | This represent the size N of our list of Integers |
2 | Minimum value an integer can take |
3 | Maximum value an integer can take |
Dependencies
Let’s add the repository:
<repositories>
<repository>
<id>gitlab-maven</id>
<url>https://gitlab.com/api/v4/projects/13863766/packages/maven</url>
</repository>
</repositories>
Then the dependency on the core module:
<dependency>
<groupId>net.bmahe.genetics4j</groupId>
<artifactId>core</artifactId>
<version>4.1</version>
</dependency>
Problem definition
And now, let’s define what we want to solve. One of the features of Genetics4j is that it cleanly separates What we want to achieve from the How we will solve it. It enables us to tweak the operators' implementation or explore different contexts, which facilitate benchmarks and exploration.
The definition of the problem is done through a fluent set of classes:
final Builder<Integer> eaConfigurationBuilder = new EAConfiguration.Builder<>();
eaConfigurationBuilder.chromosomeSpecs(IntChromosomeSpec.of(numEntries, minValue, maxValue))
.parentSelectionPolicy(Tournament.of(5))
.combinationPolicy(MultiPointCrossover.of(2))
.mutationPolicies(RandomMutation.of(0.15))
.fitness((genoType) -> {
final IntChromosome intChromosome = genoType.getChromosome(0, IntChromosome.class);
int correctCount = 0;
for (int i = 0; i < intChromosome.getNumAlleles(); i++) {
if (i == intChromosome.getAllele(i)) {
correctCount++;
}
}
return correctCount;
})
.termination(or(Terminations.ofFitnessAtLeast(numEntries), Terminations.ofMaxGeneration(50)));
final EAConfiguration<Integer> eaConfiguration = eaConfigurationBuilder.build();
Execution specification
We can next focus on the execution method through the configuration of the Evolutionary Algorithm Execution Context, which includes elements such as:
-
Population size
-
The different handlers for selection, mutation and combination
-
The different handlers for chromosome generation
-
Definition of some listeners
-
Configuration of the instance of java.util.Random to be used throughout the system
final EAExecutionContext<Integer> eaExecutionContext = EAExecutionContexts.<Integer>forScalarFitness()
.populationSize(100)
.addEvolutionListeners(EvolutionListeners.ofLogTopN(logger, 3))
.build();
Note: We have a set of factory methods to generate a EAExecutionContext. These factory methods are quite helpful as they will take care of some extra configuration. For instance, knowing the fitness value will be a scalar number enables the factory method to pre-configure some additional operators and simplify our code. See EAExecutionContexts API documentation.
Evolution
As we have defined What we want to achieve as well as How we want to do it, we can instantiate a Evolutionary Algorithm System which will be in charge of doing the actual evolution:
final EASystem<Integer> eaSystem = EASystemFactory.from(eaConfiguration, eaExecutionContext);
Finally, we can run and observe the evolution of our system and what is the best solution it finds:
final EvolutionResult<Integer> evolutionResult = eaSystem.evolve();
logger.info("Best genotype: {}", evolutionResult.bestGenotype());
logger.info(" with fitness: {}", evolutionResult.bestFitness());
logger.info(" at generation: {}", evolutionResult.generation());
And here is an example of the output of such execution:
20:59:24.015 INFO n.b.g.c.EASystem - Starting evolution 20:59:24.020 INFO n.b.g.c.EASystem - Generating initial population of 100 individuals 20:59:24.022 INFO n.b.g.c.EASystem - Generating 100 individuals 20:59:24.025 INFO n.b.g.c.EASystem - Evaluating initial population 20:59:24.032 INFO n.b.g.c.EASystem - Going through evolution of generation 0 20:59:24.032 INFO n.b.g.s.QuickStart - Top 3 individuals at generation 0 20:59:24.045 INFO n.b.g.s.QuickStart - Fitness: 3 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 4, 15, 3, 13, 5, 15, 0, 10, 3]]]] 20:59:24.045 INFO n.b.g.s.QuickStart - Fitness: 3 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[12, 4, 2, 12, 9, 9, 6, 4, 15, 9]]]] 20:59:24.045 INFO n.b.g.s.QuickStart - Fitness: 3 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 12, 4, 15, 14, 1, 6, 1, 8, 2]]]] 20:59:24.045 INFO n.b.g.c.EASystem - Selecting 200 parents as we expect to generate 100 children 20:59:24.046 INFO n.b.g.c.EASystem - Combining parents into offsprings 20:59:24.057 INFO n.b.g.c.EASystem - Generated 200 offsprings 20:59:24.057 INFO n.b.g.c.EASystem - Mutating children 20:59:24.058 INFO n.b.g.c.EASystem - Evaluating offsprings 20:59:24.059 INFO n.b.g.c.EASystem - Executing replacement strategy 20:59:24.060 INFO n.b.g.c.r.ElitismImpl - Selecting 95 offsprings 20:59:24.060 INFO n.b.g.c.r.ElitismImpl - Selecting 5 survivors 20:59:24.060 INFO n.b.g.c.EASystem - Going through evolution of generation 1 20:59:24.060 INFO n.b.g.s.QuickStart - Top 3 individuals at generation 1 20:59:24.061 INFO n.b.g.s.QuickStart - Fitness: 4 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 4, 2, 12, 9, 9, 6, 4, 15, 9]]]] 20:59:24.061 INFO n.b.g.s.QuickStart - Fitness: 4 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 4, 15, 3, 13, 5, 15, 0, 12, 9]]]] 20:59:24.061 INFO n.b.g.s.QuickStart - Fitness: 4 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 4, 2, 12, 9, 9, 6, 4, 15, 9]]]] 20:59:24.061 INFO n.b.g.c.EASystem - Selecting 200 parents as we expect to generate 100 children 20:59:24.062 INFO n.b.g.c.EASystem - Combining parents into offsprings 20:59:24.067 INFO n.b.g.c.EASystem - Generated 200 offsprings 20:59:24.067 INFO n.b.g.c.EASystem - Mutating children 20:59:24.068 INFO n.b.g.c.EASystem - Evaluating offsprings 20:59:24.068 INFO n.b.g.c.EASystem - Executing replacement strategy 20:59:24.068 INFO n.b.g.c.r.ElitismImpl - Selecting 95 offsprings 20:59:24.068 INFO n.b.g.c.r.ElitismImpl - Selecting 5 survivors 20:59:24.068 INFO n.b.g.c.EASystem - Going through evolution of generation 2 20:59:24.068 INFO n.b.g.s.QuickStart - Top 3 individuals at generation 2 20:59:24.069 INFO n.b.g.s.QuickStart - Fitness: 5 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 4, 15, 3, 13, 5, 6, 0, 12, 9]]]] 20:59:24.069 INFO n.b.g.s.QuickStart - Fitness: 5 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 4, 15, 3, 13, 5, 6, 4, 15, 9]]]] 20:59:24.069 INFO n.b.g.s.QuickStart - Fitness: 5 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 4, 15, 3, 13, 5, 6, 4, 15, 9]]]] 20:59:24.069 INFO n.b.g.c.EASystem - Selecting 200 parents as we expect to generate 100 children 20:59:24.069 INFO n.b.g.c.EASystem - Combining parents into offsprings 20:59:24.073 INFO n.b.g.c.EASystem - Generated 200 offsprings 20:59:24.073 INFO n.b.g.c.EASystem - Mutating children 20:59:24.073 INFO n.b.g.c.EASystem - Evaluating offsprings 20:59:24.074 INFO n.b.g.c.EASystem - Executing replacement strategy 20:59:24.074 INFO n.b.g.c.r.ElitismImpl - Selecting 95 offsprings 20:59:24.074 INFO n.b.g.c.r.ElitismImpl - Selecting 5 survivors 20:59:24.074 INFO n.b.g.c.EASystem - Going through evolution of generation 3 20:59:24.074 INFO n.b.g.s.QuickStart - Top 3 individuals at generation 3 20:59:24.074 INFO n.b.g.s.QuickStart - Fitness: 7 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 8, 3, 4, 10, 6, 1, 8, 9]]]] 20:59:24.075 INFO n.b.g.s.QuickStart - Fitness: 6 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 4, 2, 3, 13, 5, 6, 0, 12, 9]]]] 20:59:24.075 INFO n.b.g.s.QuickStart - Fitness: 6 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 4, 2, 3, 13, 5, 6, 0, 12, 9]]]] 20:59:24.075 INFO n.b.g.c.EASystem - Selecting 200 parents as we expect to generate 100 children 20:59:24.075 INFO n.b.g.c.EASystem - Combining parents into offsprings 20:59:24.078 INFO n.b.g.c.EASystem - Generated 200 offsprings 20:59:24.078 INFO n.b.g.c.EASystem - Mutating children 20:59:24.079 INFO n.b.g.c.EASystem - Evaluating offsprings 20:59:24.079 INFO n.b.g.c.EASystem - Executing replacement strategy 20:59:24.079 INFO n.b.g.c.r.ElitismImpl - Selecting 95 offsprings 20:59:24.079 INFO n.b.g.c.r.ElitismImpl - Selecting 5 survivors 20:59:24.080 INFO n.b.g.c.EASystem - Going through evolution of generation 4 20:59:24.080 INFO n.b.g.s.QuickStart - Top 3 individuals at generation 4 20:59:24.080 INFO n.b.g.s.QuickStart - Fitness: 8 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 8, 3, 4, 5, 6, 1, 8, 9]]]] 20:59:24.080 INFO n.b.g.s.QuickStart - Fitness: 8 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 8, 3, 4, 5, 6, 1, 8, 9]]]] 20:59:24.080 INFO n.b.g.s.QuickStart - Fitness: 7 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 19, 2, 3, 4, 5, 6, 4, 15, 9]]]] 20:59:24.080 INFO n.b.g.c.EASystem - Selecting 200 parents as we expect to generate 100 children 20:59:24.080 INFO n.b.g.c.EASystem - Combining parents into offsprings 20:59:24.083 INFO n.b.g.c.EASystem - Generated 200 offsprings 20:59:24.083 INFO n.b.g.c.EASystem - Mutating children 20:59:24.083 INFO n.b.g.c.EASystem - Evaluating offsprings 20:59:24.084 INFO n.b.g.c.EASystem - Executing replacement strategy 20:59:24.084 INFO n.b.g.c.r.ElitismImpl - Selecting 95 offsprings 20:59:24.084 INFO n.b.g.c.r.ElitismImpl - Selecting 5 survivors 20:59:24.084 INFO n.b.g.c.EASystem - Going through evolution of generation 5 20:59:24.084 INFO n.b.g.s.QuickStart - Top 3 individuals at generation 5 20:59:24.084 INFO n.b.g.s.QuickStart - Fitness: 9 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 5, 6, 1, 8, 9]]]] 20:59:24.085 INFO n.b.g.s.QuickStart - Fitness: 8 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 9, 3, 4, 5, 6, 1, 8, 9]]]] 20:59:24.085 INFO n.b.g.s.QuickStart - Fitness: 8 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 4, 6, 1, 8, 9]]]] 20:59:24.085 INFO n.b.g.c.EASystem - Selecting 200 parents as we expect to generate 100 children 20:59:24.086 INFO n.b.g.c.EASystem - Combining parents into offsprings 20:59:24.090 INFO n.b.g.c.EASystem - Generated 200 offsprings 20:59:24.090 INFO n.b.g.c.EASystem - Mutating children 20:59:24.091 INFO n.b.g.c.EASystem - Evaluating offsprings 20:59:24.091 INFO n.b.g.c.EASystem - Executing replacement strategy 20:59:24.091 INFO n.b.g.c.r.ElitismImpl - Selecting 95 offsprings 20:59:24.091 INFO n.b.g.c.r.ElitismImpl - Selecting 5 survivors 20:59:24.091 INFO n.b.g.c.EASystem - Going through evolution of generation 6 20:59:24.092 INFO n.b.g.s.QuickStart - Top 3 individuals at generation 6 20:59:24.092 INFO n.b.g.s.QuickStart - Fitness: 9 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 5, 6, 4, 8, 9]]]] 20:59:24.092 INFO n.b.g.s.QuickStart - Fitness: 9 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 5, 6, 1, 8, 9]]]] 20:59:24.092 INFO n.b.g.s.QuickStart - Fitness: 9 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 5, 6, 1, 8, 9]]]] 20:59:24.092 INFO n.b.g.c.EASystem - Selecting 200 parents as we expect to generate 100 children 20:59:24.092 INFO n.b.g.c.EASystem - Combining parents into offsprings 20:59:24.095 INFO n.b.g.c.EASystem - Generated 200 offsprings 20:59:24.095 INFO n.b.g.c.EASystem - Mutating children 20:59:24.095 INFO n.b.g.c.EASystem - Evaluating offsprings 20:59:24.096 INFO n.b.g.c.EASystem - Executing replacement strategy 20:59:24.096 INFO n.b.g.c.r.ElitismImpl - Selecting 95 offsprings 20:59:24.096 INFO n.b.g.c.r.ElitismImpl - Selecting 5 survivors 20:59:24.096 INFO n.b.g.c.EASystem - Going through evolution of generation 7 20:59:24.096 INFO n.b.g.s.QuickStart - Top 3 individuals at generation 7 20:59:24.096 INFO n.b.g.s.QuickStart - Fitness: 9 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 5, 6, 1, 8, 9]]]] 20:59:24.096 INFO n.b.g.s.QuickStart - Fitness: 9 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 5, 6, 4, 8, 9]]]] 20:59:24.097 INFO n.b.g.s.QuickStart - Fitness: 9 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 5, 6, 4, 8, 9]]]] 20:59:24.097 INFO n.b.g.c.EASystem - Selecting 200 parents as we expect to generate 100 children 20:59:24.097 INFO n.b.g.c.EASystem - Combining parents into offsprings 20:59:24.099 INFO n.b.g.c.EASystem - Generated 200 offsprings 20:59:24.099 INFO n.b.g.c.EASystem - Mutating children 20:59:24.099 INFO n.b.g.c.EASystem - Evaluating offsprings 20:59:24.099 INFO n.b.g.c.EASystem - Executing replacement strategy 20:59:24.099 INFO n.b.g.c.r.ElitismImpl - Selecting 95 offsprings 20:59:24.100 INFO n.b.g.c.r.ElitismImpl - Selecting 5 survivors 20:59:24.100 INFO n.b.g.c.EASystem - Evolution has terminated 20:59:24.100 INFO n.b.g.s.QuickStart - Top 3 individuals at generation 8 20:59:24.100 INFO n.b.g.s.QuickStart - Fitness: 10 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]]] 20:59:24.100 INFO n.b.g.s.QuickStart - Fitness: 10 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]]] 20:59:24.100 INFO n.b.g.s.QuickStart - Fitness: 10 -> Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]]] 20:59:24.103 INFO n.b.g.s.QuickStart - Best genotype: Genotype [chromosomes=[IntChromosome [size=10, minValue=0, maxValue=20, values=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]]] 20:59:24.104 INFO n.b.g.s.QuickStart - with fitness: 10 20:59:24.104 INFO n.b.g.s.QuickStart - at generation: 8
We can observe the top evolution of the top 3 solutions at each generation and how their fitnesses progressively increased, until a solution was found at the 8th generation.