Jenetics - Java Genetic Algorithm

Introduction

Jenetics is an Genetic Algorithm, respectively an Evolutionary Algorithm, library written in Java. It is designed with a clear separation of the several concepts of the algorithm, e. g. Gene, Chromosome, Genotype, Phenotype, Population and fitness Function. Jenetics allows you to minimize and maximize the given fitness function without tweaking it.

Data Structures

Structure Diagram

The diagram above shows the class-diagram of the main structures of the GA. The Gene is the base of the class structure. Genes are aggregated in Chromosomes. One to n Chromosomes are aggregated in Genotypes. A Genotype and a fitness Function from the Phenotype are collected into a Population.

Getting Started

The minimum GA setup needs a genotype factory, Factory<Genotype<?>>, and a fitness Function. The Genotype implements the Factory interface and can therefore be used as prototype for creating the initial Population and for creating new random Genotypes.

public static void main(String[] args) {
    final Factory<Genotype<BitGene>> gtf = Genotype.valueOf(
        BitChromosome.valueOf(10, 0.5)
    );
    final Function<Genotype<BitGene>, Float64> ff = ...
    final GeneticAlgorithm<BitGene, Float64> 
    ga = new GeneticAlgorithm<>(gtf, ff, Optimize.MAXIMUM)
    
    ga.setup();
    ga.evolve(100);
    System.out.println(ga.getBestPhenotype());
}

The genotype factory, gtf, in the example above will create genotypes which consists of one BitChromosome with length 10. The one to zero probability of the newly created genotypes is set to 0.5. The fitness function is parameterized with a BitGene and a Float64. That means that the fitness function is calculating the fitness value as Float64. The return type of the fitness function must be at least a Comparable. The GeneticAlgorithm object is then created with the genotype factory and the fitness function. In this example the GA tries to maximize the fitness function. If you want to find the minimal value you have to change the optimize parameter from Optimize.MAXIMUM to Optimize.MINIMUM. The ga.setup() call creates the initial population and calculates its fitness value. Then the GA evolves 100 generations (ga.evolve(100)) an prints the best phenotype found so far onto the console.

In a more advanced setup you may want to change the default mutation and/or selection strategies.

public static void main(String[] args) {
    ...
    ga.setSelectors(new RouletteWheelSelector<BitGene>());
    ga.setAlterers(
        new SinglePointCrossover<BitGene>(0.1),
        new Mutator<BitGene>(0.01)
    );

    ga.setup();
    ga.evolve(100);
    System.out.println(ga.getBestPhenotype());
}

The selection strategy for offspring and survivors are set to the roulette-wheel selector. It is also possible to set the selector for offspring and survivors independently with the setOffspringSelector and setSurvivorSelector methods. The alterers are concatenated, at first the crossover (with probability 0.1) is performed and then the chromosomes are mutated (with probability 0.01).

© Copyright Franz Wilhelmstötter