type Chromosome = char []
type Fitness = int
type Individual = Chromosome * Fitness
let target : Chromosome = [|'H'; 'e'; 'l'; 'l'; 'o'; ' '; 'F'; '#'|]
let eliteSize = 10
let delta (x: char) (y: char) =
abs( (int)x - (int)y )
let calculateFitness (target: Chromosome) (chromosome: Chromosome) =
Array.map2 (fun x y -> delta x y) target chromosome
|> Array.sum
let getFitness = calculateFitness target
let rnd = System.Random()
let createChromosome size : Individual =
let chromosome = Array.init<char> size (fun _ -> (char) (rnd.Next(32, 123)) )
let fitness = getFitness chromosome
(chromosome, fitness)
let initializePopulation withSize =
Array.init<Individual> withSize (fun _ -> createChromosome target.Length)
|> Array.sortBy (fun (_, f) -> f)
let getElite (population: Individual []) =
let size = population.Length / eliteSize
population.[..size]
let crossover (population: Individual []) =
let top50percent = population.Length / 2
let mom = fst population.[rnd.Next(top50percent)]
let dad = fst population.[rnd.Next(top50percent)]
let index = rnd.Next(target.Length)
let chromosome = Array.append mom.[..index] dad.[index + 1..]
let fitness = getFitness chromosome
(chromosome, fitness)
let newGeneration population =
let elite = getElite population
let withSize = population.Length - eliteSize
Array.init<Individual> withSize (fun _ -> crossover population)
|> Array.append elite
|> Array.sortBy (fun (_, f) -> f)
let printBest (population: Individual []) =
(fst population.[0]) |> (fun x -> System.String x) |> printfn "Best (%d): %A" (snd population.[0])
let evolve population =
let rec evolve population n =
printBest population
match (n, (snd population.[0])) with
| (0, _) -> population.[0]
| (_, 0) -> population.[0]
| _ ->
let newPopulation = newGeneration population
evolve newPopulation (n - 1)
evolve population 100
[<EntryPoint>]
let main args =
printfn "Evolve..."
let population = initializePopulation 2048
let best = evolve population
System.Console.ReadLine() |> ignore
0