Last active
March 15, 2017 02:12
-
-
Save ihavenonickname/ad8470e3145e589ab612cbd5058d3349 to your computer and use it in GitHub Desktop.
Hello genetic algorithms
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let chanceToMutate = 5 | |
let possibleChars = Array.append [|'A'..'Z'|] [|' '|] | |
let random = new System.Random() | |
let randomChar () = | |
let index = random.Next(Array.length possibleChars) | |
Array.item index possibleChars | |
let randomPopulation count individualSize = | |
let randomIndividual size = [ for _ in 1..size -> randomChar () ] | |
[ for _ in 1..count -> randomIndividual individualSize ] | |
let fitness target individual = | |
List.zip target individual | |
|> List.filter (fun (a, b) -> a = b) | |
|> List.length | |
|> fun sum -> (float sum) / float (List.length target) | |
let crossover parent1 parent2 = | |
let shouldMutate () = chanceToMutate > random.Next(100) | |
List.zip parent1 parent2 | |
|> List.map (fun (a, b) -> if random.Next(100) < 50 then a else b) | |
|> List.map (fun c -> if shouldMutate () then randomChar () else c) | |
let nextGeneration population target = | |
let count = Seq.length population | |
let pickRandom xs = List.item (random.Next(Seq.length xs)) xs | |
let chooseParents xs = (pickRandom xs, pickRandom xs) | |
let crossover (parent1, parent2) = crossover parent1 parent2 | |
let elit = | |
population | |
|> List.sortBy (fitness target) | |
|> List.skip (count / 2) | |
[ for _ in 1..count -> chooseParents elit |> crossover ] | |
let rec evolveUntillTarget population target = | |
let evolvedPopulation = nextGeneration population target | |
if List.exists (fun indiv -> indiv = target) evolvedPopulation | |
then evolvedPopulation | |
else evolveUntillTarget evolvedPopulation target | |
let find str populationCount = | |
let target = List.ofSeq str | |
let targetLength = List.length target | |
let initialPopulation = randomPopulation populationCount targetLength | |
evolveUntillTarget initialPopulation target | |
|> List.sortBy (fitness target) | |
|> List.map (List.map string) | |
|> List.map (String.concat "") | |
[<EntryPoint>] | |
let main argv = | |
printfn "started..." | |
let str = "TO BE OR NOT TO BE THAT IS THE QUESTION" | |
find str 100 |> List.iter (printfn "%O") | |
ignore <| System.Console.ReadKey() | |
0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment