Jenetics is a Genetic Algorithm, Evolutionary Algorithm, Genetic Programming, and Multi-objective Optimization library, written in modern-day Java.

zip tar.gz Maven

Currently v6.1.0

Jenetics 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. In contrast to other GA implementations, the library uses the concept of an evolution stream (EvolutionStream) for executing the evolution steps. Since the EvolutionStream implements the Java Stream interface, it works smoothly with the rest of the Java Stream API.


Multi-objective optimization

The jenetics.ext module contains classes for solving Multi-objective problems with Jenetics.

Genetic programming

The jenetics.prog module allows to do Genetic programming with Jenetics.

Frictionless minimization

No need to tweak the fitness function for minimization problems. Just change the configuration of the evolution Engine.

Plugable PRNG

Easy changeable PRNG (RandomRegistry). No special PRNG interface; the standard Java Random engine allows the use of existing random generators.

Parallel processing support

Processing of the evolutionary steps can be executed in parallel!

Dependency free

No runtime dependencies to Third Party libraries! No mismatch and class loading problems with other libraries.

Compiles and runs with Java 11/14

Fully support of Java 8 Streams and Lambdas! Stable (automatic) module names: io.jenetics.[base|ext|prog|xml]

Fully documented

Complete Documentation and User guide available.


An excellent introduction is given by Baeldung in this blog entry. There is also an introductory article series (part 1, part 2) about Jenetics in the (German) JavaSpektrum magazine, issue 01 and 03/2018.


Hello World (Ones counting)

The minimum evolution Engine 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.

import io.jenetics.BitChromosome;
import io.jenetics.BitGene;
import io.jenetics.Genotype;
import io.jenetics.engine.Engine;
import io.jenetics.engine.EvolutionResult;
import io.jenetics.util.Factory;

public class HelloWorld {
    // 2.) Definition of the fitness function.
    private static int eval(Genotype<BitGene> gt) {
        return gt.chromosome()

    public static void main(String[] args) {
        // 1.) Define the genotype (factory) suitable
        //     for the problem.
        Factory<Genotype<BitGene>> gtf =
            Genotype.of(BitChromosome.of(10, 0.5));

        // 3.) Create the execution environment.
        Engine<BitGene, Integer> engine = Engine
            .builder(HelloWorld::eval, gtf)

        // 4.) Start the execution (evolution) and
        //     collect the result.
        Genotype<BitGene> result =

        System.out.println("Hello World:\n" + result);
In contrast to other GA implementations, the library uses the concept of an evolution stream (EvolutionStream) for executing the evolution steps. Since the EvolutionStream implements the Java Stream interface, it works smoothly with the rest of the Java streaming API. Now let's have a closer look at listing above and discuss this simple program step by step:
  1. The probably most challenging part, when setting up a new evolution Engine, is to transform the problem domain into a appropriate Genotype (factory) representation. In our example we want to count the number of ones of a BitChromosome. Since we are counting only the ones of one chromosome, we are adding only one BitChromosome to our Genotype. In general, the Genotype can be created with 1 to n chromosomes.
  2. Once this is done, the fitness function which should be maximized, can be defined. Utilizing the new language features introduced in Java 8, we simply write a private static method, which takes the genotype we defined and calculate it's fitness value. If we want to use the optimized bit-counting method, bitCount(), we have to cast the Chromosome<BitGene> class to the actual used BitChromosome class. Since we know for sure that we created the Genotype with a BitChromosome, this can be done safely. A reference to the eval method is then used as fitness function and passed to the method.
  3. In the third step we are creating the evolution Engine, which is responsible for changing, respectively evolving, a given population. The Engine is highly configurable and takes parameters for controlling the evolutionary and the computational environment. For changing the evolutionary behavior, you can set different alterers and selectors. By changing the used Executor service, you control the number of threads, the Engine is allowed to use. An new Engine instance can only be created via its builder, which is created by calling the Engine.builder method.
  4. In the last step, we can create a new EvolutionStream from our Engine. The EvolutionStream is the model or view of the evolutionary process. It serves as a »process handle« and also allows you, among other things, to control the termination of the evolution. In our example, we simply truncate the stream after 100 generations. If you don't limit the stream, the EvolutionStream will not terminate and run forever. Since the EvolutionStream extends the interface, it integrates smoothly with the rest of the Java Stream API. The final result, the best Genotype in our example, is then collected with one of the predefined collectors of the EvolutionResult class.

Evolving images

This example tries to approximate a given image by semitransparent polygons. It comes with an Swing UI, where you can immediately start your own experiments.

Evolving Mona Lisa

For a detailed description on how to execute this example, have a look at the Github project page.

Symbolic regression (GP)

Symbolic regression involves finding a mathematical expression, in symbolic form, that provides a good, best, or perfect fit between a given finite sampling of values of the independent variables and the associated values of the dependent variables. --- John R. Koza

Symbolic regression is a classical example in genetic programming and tries to find a mathematical expression for a given set of values. The example shows how to solve the GP problem with Jenetics. We are trying to find the polynomial, 4x3 - 3x2 + x, which fits a given data set. The sample data where created with the polynomial we are searching for. This makes it easy to check the quality of the approximation found by the GP.

Extension modules

Additional modules

This libraries doesn't have any dependency to Jenetics and can be used as they are.

  • io.jenetics.prngine: A pseudo-random number generator library for sequential and parallel Monte Carlo simulations. It has been designed to work smoothly with the Jenetics library, but it has no dependency to it. All PRNG implementations of this library extends the Java Random class, which makes it easily usable in other projects.
  • io.jenetics.jpx: A Java library for creating, reading and writing GPS data in GPX format. It is a full implementation of version 1.1 of the GPX format. The data classes are completely immutable and allows a functional programming style. They are working also nicely with the Java 8 Stream API. Since it is also possible to calculate the distance between way-points, it is a good fit for the TSP.

Other languages

  • Jenetics.NET: Experimental .NET Core port in C# of the base library.
  • Helise: Scala wrapper around the Jenetics library.

Projects using Jenetics

  • Renaissance Suite: Renaissance is a modern, open, and diversified benchmark suite for the JVM, aimed at testing JIT compilers, garbage collectors, profilers, analyzers and other tools.
  • Chartsy|One: Chartsy|One is a Netbeans based tool for stock market investors and traders.
  • Chronetic: Chronetic is an open-source time pattern analysis library built to describe time-series data.
  • APP4MC: Eclipse APP4MC is a platform for engineering embedded multi- and many-core software systems.

Blogs and articles


Used software