-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathfsharp_OO.fs
57 lines (41 loc) · 1.7 KB
/
fsharp_OO.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
open System
let goal = List.ofArray("methinks it is like a weasel".ToCharArray())
let genepool = "abcdefghijklmnopqrstuvwxyz "
let factor = 0.04
let litterSize = 100
let rng = new Random()
/// Get a random 'gene, as in a random character from the 'genepool'.
let randomGene = (fun _ -> genepool.[rng.Next(genepool.Length)])
/// Mutates a 'gene' if the magic powers of pseudo-randomness allows it to be so.
let mutateGene c =
if rng.NextDouble() < factor then randomGene()
else c
type Weasel private (genes:char list) =
member this.Genes = genes
member this.Score =
(List.zip genes goal
|> List.map (fun (x, y) -> x = y)
|> List.filter (fun x -> x)).Length
new (parent:Weasel) = Weasel(List.map mutateGene parent.Genes)
new () = Weasel([for a in [1 .. goal.Length] do
yield randomGene()])
member this.GiveBirth =
[for a in [1 .. litterSize] do
yield Weasel(List.map mutateGene this.Genes)]
static member FindFittest (lst:Weasel list) =
let sorted = List.sortBy (fun (w:Weasel) -> -w.Score) lst
List.nth sorted 0
let main() =
// Recursively apply the process of evolution
let rec evolution (curr:Weasel, iter:int) =
printf "%d\t%d\t" iter curr.Score
printf "%s\n" (String.Concat(curr.Genes))
let fittest = Weasel.FindFittest(curr.GiveBirth)
match fittest with
| f when f.Score = goal.Length -> (fittest, (iter + 1))
| _ -> evolution (fittest, (iter + 1))
// begin the evolution
evolution (new Weasel(), 0)
let winner = main()
printf "Winner: %s\nIt took %d generations" (String.Concat((fst(winner)).Genes)) (snd(winner))
Console.ReadKey() |> ignore