RosettaCodeData/Task/Evolutionary-algorithm/Elena/evolutionary-algorithm.elena

66 lines
1.6 KiB
Plaintext

#import system.
#import system'routines.
#import extensions.
#symbol Target = "METHINKS IT IS LIKE A WEASEL".
#symbol AllowedCharacters = " ABCDEFGHIJKLMNOPQRSTUVWXYZ".
#symbol C = 100.
#symbol P = 0.05r.
#symbol rnd = randomGenerator.
#symbol randomChar
= AllowedCharacters @ (rnd nextInt:(AllowedCharacters length)).
#class(extension) evoHelper
{
#method randomString
= 0 repeat &till:self &each:x [ randomChar ] summarize:(String new) literal.
#method fitness &of:s
= self zip:s &into:(:a:b)[ (a == b)iif:1:0 ] summarize:(Integer new) int.
#method mutate : p
= self select &each: ch [ (rnd nextReal <= p) iif:randomChar:ch ] summarize:(String new) literal.
}
#class EvoAlgorithm :: Enumerator
{
#field theTarget.
#field theCurrent.
#field theVariantCount.
#constructor new : s &of:count
[
theTarget := s.
theVariantCount := count int.
]
#method get = theCurrent.
#method next
[
($nil == theCurrent)
? [ theCurrent := theTarget length randomString. ^ true. ].
(theTarget == theCurrent)
? [ ^ false. ].
#var variants := Array new:theVariantCount set &every:(&index:x) [ theCurrent mutate:P ].
theCurrent := variants array sort:(:a:b) [ a fitness &of:Target > b fitness &of:Target ] getAt:0.
^ true.
]
}
#symbol program =
[
#var attempt := Integer new.
EvoAlgorithm new:Target &of:C run &each:current
[
console
writeLiteral:"#":(attempt += 1) &paddingLeft:10
writeLine:" ":current:" fitness: ":(current fitness &of:Target).
].
].