Data update

This commit is contained in:
Ingy döt Net 2024-03-06 22:25:12 -08:00
parent ed705008a8
commit 0df55f9f24
2196 changed files with 32999 additions and 3075 deletions

View file

@ -0,0 +1,63 @@
import 'dart:math';
class EvoAlgo {
static final String target = "METHINKS IT IS LIKE A WEASEL";
static final List<String> possibilities = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ".split('');
static int c = 100; // Number of spawn per generation
static double minMutateRate = 0.09;
static int perfectFitness = target.length;
static String parent = '';
static Random rand = Random();
static int fitness(String trial) {
int retVal = 0;
for (int i = 0; i < trial.length; i++) {
if (trial[i] == target[i]) retVal++;
}
return retVal;
}
static double newMutateRate() {
return (((perfectFitness - fitness(parent)) / perfectFitness) * (1 - minMutateRate));
}
static String mutate(String parent, double rate) {
String retVal = '';
for (int i = 0; i < parent.length; i++) {
retVal += (rand.nextDouble() <= rate)
? possibilities[rand.nextInt(possibilities.length)]
: parent[i];
}
return retVal;
}
static void main() {
parent = mutate(target, 1);
int iter = 0;
while (parent != target) {
double rate = newMutateRate();
iter++;
if (iter % 100 == 0) {
print('$iter: $parent, fitness: ${fitness(parent)}, rate: $rate');
}
String bestSpawn;
int bestFit = 0;
for (int i = 0; i < c; i++) {
String spawn = mutate(parent, rate);
int fit = fitness(spawn);
if (fit > bestFit) {
bestSpawn = spawn;
bestFit = fit;
}
}
if (bestFit > fitness(parent)) {
parent = bestSpawn;
}
}
print('$parent, $iter');
}
}
void main() {
EvoAlgo.main();
}

View file

@ -16,13 +16,13 @@ randomChar
extension evoHelper
{
randomString()
= 0.repeatTill(self).selectBy:(x => randomChar).summarize(new StringWriter());
= 0.repeatTill(self).selectBy::(x => randomChar).summarize(new StringWriter());
fitnessOf(s)
= self.zipBy(s, (a,b => a==b ? 1 : 0)).summarize(new Integer()).toInt();
mutate(p)
= self.selectBy:(ch => rnd.nextReal() <= p ? randomChar : ch).summarize(new StringWriter());
= self.selectBy::(ch => rnd.nextReal() <= p ? randomChar : ch).summarize(new StringWriter());
}
class EvoAlgorithm : Enumerator
@ -47,9 +47,9 @@ class EvoAlgorithm : Enumerator
if (_target == _current)
{ ^ false };
auto variants := Array.allocate(_variantCount).populate:(x => _current.mutate:P );
auto variants := Array.allocate(_variantCount).populate::(x => _current.mutate(P) );
_current := variants.sort:(a,b => a.fitnessOf:Target > b.fitnessOf:Target ).at:0;
_current := variants.sort::(a,b => a.fitnessOf(Target) > b.fitnessOf(Target) ).at(0);
^ true
}
@ -65,7 +65,7 @@ class EvoAlgorithm : Enumerator
public program()
{
var attempt := new Integer();
EvoAlgorithm.new(Target,C).forEach:(current)
EvoAlgorithm.new(Target,C).forEach::(current)
{
console
.printPaddingLeft(10,"#",attempt.append(1))

View file

@ -0,0 +1,64 @@
# Assumption: input consists of random three-digit numbers i.e. 000 to 999
def rand: input;
def set: "ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
def abs:
if . < 0 then -. else . end;
def ichar:
if type == "number" then . else explode[0] end;
# Output: a pseudo-random character from set.
# $n should be a random number drawn from range(0; N) inclusive where N > set|length
# Input: an admissible character from `set` (ignored in this implementation)
def shift($n):
($n % (set|length)) as $i
| set[$i:$i+1];
# fitness: 0 indicates a perfect fit; greater numbers indicate worse fit.
def fitness($gold):
def diff($c; $d): ($c|ichar) - ($d|ichar) | abs;
. as $in
| reduce range(0;length) as $i (0; . + diff($in[$i:$i+1]; $gold[$i:$i+1]));
# Input: a string
# Output: a mutation of . such that each character is mutated with probability $r
def mutate($r):
# Output: a pseudo-random character from set
# $n should be a random number drawn from range(0; N) inclusive where N > set|length
def letter($n):
($n % (set|length)) as $i
| set[$i:$i+1];
. as $p
| reduce range(0;length) as $i ("";
rand as $rand
| if ($rand/1000) < $r then . + letter($rand)
else . + $p[$i:$i+1]
end );
# An array of $n children of the parent provided as input; $r is the mutation probability
def children($n; $r):
[range(0;$n) as $i | mutate($r)];
# Input: a "parent"
# Output: a single string
def next_generation($gold; $r):
([.] + children(100; $r))
| min_by( fitness($gold) );
# Evolve towards the target string provided as input, using $r as the mutation rate;
# `recurse` is used in order to show progress conveniently.
def evolve($r):
. as $gold
| (set|length) as $s
| (reduce range(0; $n) as $i (""; (rand % $s) as $j | . + set[$j:$j+1])) as $string
| {count: 0, $string }
| recurse (
if .string | fitness($gold) == 0 then empty
else .string |= next_generation($gold; $r)
| .count += 1
end);
"METHINKS IT IS LIKE A WEASEL" | evolve(0.05)