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

77 lines
1.7 KiB
Text
Raw Permalink Normal View History

2019-09-12 10:33:56 -07:00
import system'routines;
import extensions;
import extensions'text;
2016-12-05 22:15:40 +01:00
2019-09-12 10:33:56 -07:00
const string Target = "METHINKS IT IS LIKE A WEASEL";
const string AllowedCharacters = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2016-12-05 22:15:40 +01:00
2019-09-12 10:33:56 -07:00
const int C = 100;
const real P = 0.05r;
2016-12-05 22:15:40 +01:00
2019-09-12 10:33:56 -07:00
rnd = randomGenerator;
2017-09-23 10:01:46 +02:00
randomChar
2019-09-12 10:33:56 -07:00
= AllowedCharacters[rnd.nextInt(AllowedCharacters.Length)];
2017-09-23 10:01:46 +02:00
extension evoHelper
2016-12-05 22:15:40 +01:00
{
2019-09-12 10:33:56 -07:00
randomString()
= 0.repeatTill(self).selectBy:(x => randomChar).summarize(new StringWriter());
2016-12-05 22:15:40 +01:00
2019-09-12 10:33:56 -07:00
fitnessOf(s)
= self.zipBy(s, (a,b => a==b ? 1 : 0)).summarize(new Integer()).toInt();
2016-12-05 22:15:40 +01:00
2019-09-12 10:33:56 -07:00
mutate(p)
= self.selectBy:(ch => rnd.nextReal() <= p ? randomChar : ch).summarize(new StringWriter());
2016-12-05 22:15:40 +01:00
}
2019-09-12 10:33:56 -07:00
class EvoAlgorithm : Enumerator
2016-12-05 22:15:40 +01:00
{
2019-09-12 10:33:56 -07:00
object theTarget;
object theCurrent;
object theVariantCount;
2016-12-05 22:15:40 +01:00
2019-09-12 10:33:56 -07:00
constructor new:of(s,count)
{
theTarget := s;
theVariantCount := count.toInt();
}
2016-12-05 22:15:40 +01:00
2019-09-12 10:33:56 -07:00
get() = theCurrent;
2016-12-05 22:15:40 +01:00
2019-09-12 10:33:56 -07:00
bool next()
{
if (nil == theCurrent)
{ theCurrent := theTarget.Length.randomString(); ^ true };
2016-12-05 22:15:40 +01:00
2017-09-23 10:01:46 +02:00
if (theTarget == theCurrent)
2019-09-12 10:33:56 -07:00
{ ^ false };
2016-12-05 22:15:40 +01:00
2019-09-12 10:33:56 -07:00
auto variants := Array.allocate(theVariantCount).populate:(x => theCurrent.mutate:P );
2016-12-05 22:15:40 +01:00
2019-09-12 10:33:56 -07:00
theCurrent := variants.sort:(a,b => a.fitnessOf:Target > b.fitnessOf:Target ).at:0;
2016-12-05 22:15:40 +01:00
2019-09-12 10:33:56 -07:00
^ true
}
reset()
{
theCurrent := nil
}
enumerable() => theTarget;
2016-12-05 22:15:40 +01:00
}
2019-09-12 10:33:56 -07:00
public program()
{
var attempt := new Integer();
2020-02-17 23:21:07 -08:00
EvoAlgorithm.new:Target &of:C.forEach:(current)
2019-09-12 10:33:56 -07:00
{
2016-12-05 22:15:40 +01:00
console
2019-09-12 10:33:56 -07:00
.printPaddingLeft(10,"#",attempt.append(1))
.printLine(" ",current," fitness: ",current.fitnessOf(Target))
};
2017-09-23 10:01:46 +02:00
2019-09-12 10:33:56 -07:00
console.readChar()
}