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()