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

77 lines
1.6 KiB
Text
Raw Permalink Normal View History

2023-07-01 11:58:00 -04:00
import system'routines;
import extensions;
import extensions'text;
const string Target = "METHINKS IT IS LIKE A WEASEL";
const string AllowedCharacters = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const int C = 100;
const real P = 0.05r;
rnd = randomGenerator;
randomChar
= AllowedCharacters[rnd.nextInt(AllowedCharacters.Length)];
extension evoHelper
{
randomString()
2024-03-06 22:25:12 -08:00
= 0.repeatTill(self).selectBy::(x => randomChar).summarize(new StringWriter());
2023-07-01 11:58:00 -04:00
fitnessOf(s)
= self.zipBy(s, (a,b => a==b ? 1 : 0)).summarize(new Integer()).toInt();
mutate(p)
2024-03-06 22:25:12 -08:00
= self.selectBy::(ch => rnd.nextReal() <= p ? randomChar : ch).summarize(new StringWriter());
2023-07-01 11:58:00 -04:00
}
class EvoAlgorithm : Enumerator
{
2023-10-02 18:11:16 -07:00
object _target;
object _current;
object _variantCount;
2023-07-01 11:58:00 -04:00
constructor new(s,count)
{
2023-10-02 18:11:16 -07:00
_target := s;
_variantCount := count.toInt();
2023-07-01 11:58:00 -04:00
}
2023-10-02 18:11:16 -07:00
get Value() = _current;
2023-07-01 11:58:00 -04:00
bool next()
{
2023-10-02 18:11:16 -07:00
if (nil == _current)
{ _current := _target.Length.randomString(); ^ true };
2023-07-01 11:58:00 -04:00
2023-10-02 18:11:16 -07:00
if (_target == _current)
2023-07-01 11:58:00 -04:00
{ ^ false };
2024-03-06 22:25:12 -08:00
auto variants := Array.allocate(_variantCount).populate::(x => _current.mutate(P) );
2023-07-01 11:58:00 -04:00
2024-03-06 22:25:12 -08:00
_current := variants.sort::(a,b => a.fitnessOf(Target) > b.fitnessOf(Target) ).at(0);
2023-07-01 11:58:00 -04:00
^ true
}
reset()
{
2023-10-02 18:11:16 -07:00
_current := nil
2023-07-01 11:58:00 -04:00
}
2023-10-02 18:11:16 -07:00
enumerable() => _target;
2023-07-01 11:58:00 -04:00
}
public program()
{
var attempt := new Integer();
2024-03-06 22:25:12 -08:00
EvoAlgorithm.new(Target,C).forEach::(current)
2023-07-01 11:58:00 -04:00
{
console
.printPaddingLeft(10,"#",attempt.append(1))
.printLine(" ",current," fitness: ",current.fitnessOf(Target))
};
console.readChar()
}