66 lines
1.6 KiB
Plaintext
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).
|
|
].
|
|
].
|