Skip to content
Scala API for jenetics
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
project Added release stuff. Dec 22, 2018
src Further cleaned up API, filled up Scaladoc. Dec 4, 2018
.gitignore First version of the API, incl/ demo. May 22, 2018
.scalafmt.conf
LICENSE Initial commit May 9, 2018
README.adoc Added release information. Dec 22, 2018
build.sbt Removed explicit version in lieu of dynver. Dec 22, 2018

README.adoc

Helisa

Latest 2.12 version

What is it?

Helisa (HEL-EE-SAH) is a Scala frontend for solving problems with genetic algorithms and genetic programming.

It’s pretty much a Scala wrapper around the excellent jenetics library [1].

How to use it

Obtaining

helisa is available on Maven central through:

"com.softwaremill" %% "helisa" % "0.8.0"

Currently only Scala 2.12 is supported.

Basic usage

The two things that are absolutely required are:

  1. A genotype, i.e. a representation of possible solutions to the problem,

  2. a fitness function, that scores the solutions generated from the genotypes.

Using an example for guessing a number between 0 and a 100, you would have:

import com.softwaremill.helisa._

case class Guess(num: Int) (1)

val genotype =
  () => genotypes.uniform(chromosomes.int(0, 100)) (2)
def fitness(toGuess: Int) =
  (guess: Guess) => 1.0 / (guess.num - toGuess).abs (3)
  1. The representation of a solution to the problem (the phenotype)

  2. A producer of genotypes.

  3. The fitness function - the closer to the target number, the higher the fitness score.

We use the code above to set up the Evolver, which encapsulates all configuration and generates fresh population streams:

val evolver =
  Evolver(fitness(Number), genotype) (1)
    .populationSize(100) (2)
    .build()

val stream = evolver.streamScalaStdLib() (3)

val best = stream.drop(1000).head.bestPhenotype (4)

println(best)
// Some(Guess(42))
  1. Initialize the Evolver with our genotype and fitness function.

  2. Set the population size.

  3. Obtain a Stream population stream (see Integrating for more information)

  4. Advance the stream and obtain the highest-scored phenotype.

Validation

You can additionally restrict the solution space by adding a phenotype validator:

val evolver =
  Evolver(fitness(Number), genotype)
    .populationSize(100)
    .phenotypeValidator(_.num % 2 == 0) (1)
    .build()
  1. We know the number is even, so we’re restricting possible solutions to only those numbers.

Operators

As a reminder, the three main elements of evolution in genetic algorithms are:

  • the selection of fittest individuals (phenotypes),

  • the recombination of selected individuals to form new individuals in the next generation of the population,

  • the mutation of the new/remaining individuals.

Selection

Standard selectors are available from helisa.selectors, you use them like this:

import com.softwaremill.helisa._

val evolver =
  Evolver(fitnessFunction, genotype)
   .offspringSelector(selectors.x) (1)
   .survivorsSelector(selectors.y) (2)
    .build()
  1. Affect just the survivors.

  2. Affects both the survivors and offspring.

You can also add a custom selector by passing the appropriate function to the survivorSelectorAsFunction or offspringSelectorAsFunction method.

Recombination and mutation

Recombination and mutation is handled are both generalized to operators, available in helisa.operators . You use them as follows:

import com.softwaremill.helisa._

val evolver =
  Evolver(fitnessFunction, genotype)
   .geneticOperators(operators.crossover.x, (1)
   operators.mutation.y) (2)
    .build()
  1. Recombination operators.

  2. Mutation operators.

You can also add a custom operator by passing the appropriate function to the geneticOperatorsAsFunctions method.

Other configuration

See the doc of EvolverBuilder for all Evolver configuration options.

Integrating

Integrations for:

  • scala.collection.Iterator

  • scala.collection.Stream

  • Akka Stream Source

  • FS2 Stream for any Async

  • Reactive Streams Publisher

In addition:

  • Monix is not supported directly, but can be taken advantage with using the other integrations,

  • Spark integration is coming up.

Genetic programming

TBD

You can’t perform that action at this time.