# Evolutionary Algorithms

## Genetic Algorithms

See the wikipedia page on Genetic Algorithms

## Example: Rabbits

Consider a `Rabbit` class

``case class Rabbit(a: Int, b: Double, c: Double, d: Double, e: Double, f: Double, g: Double, h: Double)``

Define the `Species` for a Genetic Algorithm, which requires a random generator and a fitness function.

``````import shapeless._

val gen = Generic[Rabbit]

import axle.ml._

import scala.util.Random.nextDouble
import scala.util.Random.nextInt

implicit val rabbitSpecies = new Species[gen.Repr] {

def random(rg: spire.random.Generator): gen.Repr = {

val rabbit = Rabbit(
1 + nextInt(2),
5 + 20 * nextDouble(),
1 + 4 * nextDouble(),
3 + 10 * nextDouble(),
10 + 5 * nextDouble(),
2 + 2 * nextDouble(),
3 + 5 * nextDouble(),
2 + 10 * nextDouble())
gen.to(rabbit)
}

def fitness(rg: gen.Repr): Double = {
val rabbit = gen.from(rg)
import rabbit._
a * 100 + 100.0 * b + 2.2 * (1.1 * c + 0.3 * d) + 1.3 * (1.4 * e - 3.1 * f + 1.3 * g) - 1.4 * h
}

}``````

Run the genetic algorithm

``````import cats.implicits._

val ga = GeneticAlgorithm(populationSize = 100, numGenerations = 100)

val log = ga.run(spire.random.Generator.rng)``````
``````val winner = log.winners.last
// winner: gen.Repr = 2 :: 24.928269028394595 :: 4.969432787921576 :: 12.746095542268307 :: 14.766726800659342 :: 2.1645513304860007 :: 7.892561260630583 :: 2.8479115995915842 :: HNil``````

Plot the min, average, and max fitness function by generation

``````import scala.collection.immutable.TreeMap
import axle.visualize._

val plot = Plot[String, Int, Double, TreeMap[Int,Double]](
() => List("min" -> log.mins, "ave" -> log.aves, "max" -> log.maxs),
connect = true,
colorOf = (label: String) => label match {
case "min" => Color.black
case "ave" => Color.blue
case "max" => Color.green },
title = Some("GA Demo"),
xAxis = Some(0d),
xAxisLabel = Some("generation"),
yAxis = Some(0),
yAxisLabel = Some("fitness"))``````

Render to an SVG file

``````import axle.web._
import cats.effect._

plot.svg[IO]("docwork/images/ga.svg").unsafeRunSync()``````