Implementation:Haifengl Smile GeneticAlgorithm
| Knowledge Sources | |
|---|---|
| Domains | Genetic Algorithms, Optimization, Evolutionary Computation, Metaheuristics |
| Last Updated | 2026-02-08 22:00 GMT |
Overview
GeneticAlgorithm is the main evolutionary optimization engine in the Smile genetic algorithm package that evolves a population of chromosomes toward better solutions through selection, crossover, and mutation.
Description
The GeneticAlgorithm<T extends Chromosome<T>> class implements a standard genetic algorithm with support for Lamarckian evolution. It manages a population of chromosomes and iteratively applies selection, crossover, and mutation operators to evolve the population over multiple generations.
Key features:
- Elitism -- copies the best chromosome(s) directly to the next generation to prevent losing the best solution found so far. The default elitism is 1.
- Configurable selection -- supports pluggable selection strategies via the
Selectioninterface. The default is tournament selection with size 3 and probability 0.95. - Parallel fitness evaluation -- fitness is evaluated in parallel using Java's parallel streams.
- Lamarckian evolution -- if chromosomes implement
LamarckianChromosome, local search steps are performed during fitness evaluation. The number of local search steps defaults to 5 and is configurable. - Early stopping -- evolution can terminate early if a fitness threshold is exceeded.
The evolution loop at each generation:
- Copy elite chromosomes to the new population.
- Select parents using the selection strategy.
- Apply crossover to produce offspring.
- Apply mutation to offspring.
- Evaluate fitness (in parallel).
- Sort the population by fitness.
Usage
Use GeneticAlgorithm as the main driver for evolutionary optimization. Provide an initial population of chromosomes (e.g., BitString objects), configure selection and elitism, then call evolve() to run the optimization.
Code Reference
Source Location
- Repository: Haifengl_Smile
- File: base/src/main/java/smile/gap/GeneticAlgorithm.java
- Lines: 1-297
Signature
public class GeneticAlgorithm<T extends Chromosome<T>> {
// Constructors
public GeneticAlgorithm(T[] seeds);
public GeneticAlgorithm(T[] seeds, Selection selection, int elitism);
// Configuration
public T[] population();
public GeneticAlgorithm<T> setLocalSearchSteps(int t);
public int getLocalSearchSteps();
// Evolution
public T evolve(int generation);
public T evolve(int generation, double threshold);
}
Import
import smile.gap.GeneticAlgorithm;
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| seeds | T[] | Yes | The initial population of chromosomes, typically randomly generated. |
| selection | Selection | No (default Tournament(3, 0.95)) | The selection strategy for choosing parents. |
| elitism | int | No (default 1) | The number of best chromosomes to copy directly to the next generation. Must be >= 0 and < population size. |
| generation | int | Yes (evolve) | The number of generations to evolve. Must be positive. |
| threshold | double | No (default POSITIVE_INFINITY) | Fitness threshold for early stopping. |
| t | int | No (default 5) | The number of local search iterations for Lamarckian evolution. Set to 0 to disable. |
Outputs
| Name | Type | Description |
|---|---|---|
| evolve() | T | The best chromosome from the final generation in terms of fitness. |
| population() | T[] | The current population array (sorted by fitness after evolution). |
Usage Examples
Basic Usage
import smile.gap.BitString;
import smile.gap.Fitness;
import smile.gap.GeneticAlgorithm;
// OneMax problem: maximize number of 1-bits
Fitness<BitString> oneMax = ch -> {
byte[] bits = ch.bits();
int count = 0;
for (byte b : bits) count += b;
return count;
};
// Create initial population
BitString[] population = new BitString[50];
for (int i = 0; i < population.length; i++) {
population[i] = new BitString(100, oneMax);
}
// Default GA: tournament selection, elitism = 1
GeneticAlgorithm<BitString> ga = new GeneticAlgorithm<>(population);
BitString best = ga.evolve(500);
System.out.println("Best fitness: " + best.fitness());
Custom Selection and Early Stopping
import smile.gap.BitString;
import smile.gap.Fitness;
import smile.gap.GeneticAlgorithm;
import smile.gap.Selection;
Fitness<BitString> fitness = ch -> {
byte[] bits = ch.bits();
int count = 0;
for (byte b : bits) count += b;
return count;
};
BitString[] population = new BitString[100];
for (int i = 0; i < population.length; i++) {
population[i] = new BitString(64, fitness);
}
// Use rank selection with elitism of 2
Selection selection = Selection.Rank();
GeneticAlgorithm<BitString> ga = new GeneticAlgorithm<>(population, selection, 2);
// Disable Lamarckian local search
ga.setLocalSearchSteps(0);
// Evolve up to 1000 generations, stop early if fitness reaches 64
BitString best = ga.evolve(1000, 64.0);
System.out.println("Best fitness: " + best.fitness());