52 lines
1.6 KiB
Plaintext
52 lines
1.6 KiB
Plaintext
global target, chars, parent, C, M, current_fitness
|
|
|
|
procedure fitness(s)
|
|
fit := 0
|
|
#Increment the fitness for every position in the string s that matches the target
|
|
every i := 1 to *target & s[i] == target[i] do fit +:= 1
|
|
return fit
|
|
end
|
|
|
|
procedure mutate(s)
|
|
#If a random number between 0 and 1 is inside the bounds of mutation randomly alter a character in the string
|
|
if (?0 <= M) then ?s := ?chars
|
|
return s
|
|
end
|
|
|
|
procedure generation()
|
|
population := [ ]
|
|
next_parent := ""
|
|
next_fitness := -1
|
|
|
|
#Create the next population
|
|
every 1 to C do push(population, mutate(parent))
|
|
#Find the member of the population with highest fitness, or use the last one inspected
|
|
every x := !population & (xf := fitness(x)) > next_fitness do {
|
|
next_parent := x
|
|
next_fitness := xf
|
|
}
|
|
|
|
parent := next_parent
|
|
|
|
return next_fitness
|
|
end
|
|
|
|
procedure main()
|
|
target := "METHINKS IT IS LIKE A WEASEL" #Our target string
|
|
chars := &ucase ++ " " #Set of usable characters
|
|
parent := "" & every 1 to *target do parent ||:= ?chars #The universal common ancestor!
|
|
current_fitness := fitness(parent) #The best fitness we have so far
|
|
|
|
|
|
C := 50 #Population size in each generation
|
|
M := 0.5 #Mutation rate per individual in a generation
|
|
|
|
gen := 1
|
|
#Until current fitness reaches a score of perfect match with the target string keep generating new populations
|
|
until ((current_fitness := generation()) = *target) do {
|
|
write(gen || " " || current_fitness || " " || parent)
|
|
gen +:= 1
|
|
}
|
|
write("At generation " || gen || " we found a string with perfect fitness at " || current_fitness || " reading: " || parent)
|
|
end
|