This commit is contained in:
Ingy döt Net 2013-10-27 22:24:23 +00:00
parent 6f050a029e
commit 776bba907c
3887 changed files with 59894 additions and 7280 deletions

View file

@ -0,0 +1,83 @@
integer
fitness(data t, data b)
{
integer f, i;
f = 0;
i = b_length(t);
while (i) {
i -= 1;
f += sign(b_character(t, i) ^ b_character(b, i));
}
return f;
}
void
mutate(data c, data b, data u)
{
integer i, l;
l = b_length(b);
i = 0;
while (i < l) {
if (drand(15)) {
b_append(c, b_character(b, i));
} else {
b_append(c, b_character(u, drand(26)));
}
i += 1;
}
}
integer
main(void)
{
data b, t, u;
integer f, i, l;
b_cast(t, "METHINK IT IS LIKE A WEASEL");
b_cast(u, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ");
l = b_length(t);
i = l;
while (i) {
i -= 1;
b_append(b, b_character(u, drand(26)));
}
f = fitness(t, b);
while (f) {
data n;
integer a;
o_winteger(-4, f);
o_text(b_string(b));
o_newline();
n = b;
i = 32;
while (i) {
data c;
i -= 1;
mutate(c, b, u);
a = fitness(t, c);
if (a < f) {
f = a;
n = c;
}
}
b = n;
}
o_winteger(-4, f);
o_text(b_string(b));
o_newline();
return 0;
}

View file

@ -10,7 +10,7 @@ enum mut= (dchar[] s) => s.map!(a=> uniform(0,1.) < P ? rnd : a).array;
void main() {
auto parent = target.length.iota.map!(_ => rnd).array;
for (auto gen = 1; parent != target; gen++) {
//parent = parent.repeat(C).map!mut.array.max!(s => s.fitness);
// parent = parent.repeat(C).map!mut.array.max!fitness;
parent = parent.repeat(C).map!mut.array
.minPos!((a, b) => a.fitness < b.fitness)[0];
writefln("Gen %2d, dist=%2d: %s", gen, parent.fitness, parent);

View file

@ -4,7 +4,7 @@ import Data.List
import Data.Ord
import Data.Array
showNum :: (Num a) => Int -> a -> String
showNum :: (Num a, Show a) => Int -> a -> String
showNum w = until ((>w-1).length) (' ':) . show
replace :: Int -> a -> [a] -> [a]

View file

@ -1,5 +1,4 @@
import System
import Random
import System.Random
import Data.List
import Data.Ord
import Data.Array

View file

@ -0,0 +1,45 @@
define('TARGET','METHINKS IT IS LIKE A WEASEL');
define('TBL','ABCDEFGHIJKLMNOPQRSTUVWXYZ ');
define('MUTATE',15);
define('COPIES',30);
define('TARGET_COUNT',strlen(TARGET));
define('TBL_COUNT',strlen(TBL));
// Determine number of different chars between a and b
function unfitness($a,$b)
{
$sum=0;
for($i=0;$i<strlen($a);$i++)
if($a[$i]!=$b[$i]) $sum++;
return($sum);
}
function mutate($a)
{
$tbl=TBL;
for($i=0;$i<strlen($a);$i++) $out[$i]=mt_rand(0,MUTATE)?$a[$i]:$tbl[mt_rand(0,TBL_COUNT-1)];
return(implode('',$out));
}
$tbl=TBL;
for($i=0;$i<TARGET_COUNT;$i++) $tspec[$i]=$tbl[mt_rand(0,TBL_COUNT-1)];
$parent[0]=implode('',$tspec);
$best=TARGET_COUNT+1;
$iters=0;
do {
for($i=1;$i<COPIES;$i++) $parent[$i]=mutate($parent[0]);
for($best_i=$i=0; $i<COPIES;$i++) {
$unfit=unfitness(TARGET,$parent[$i]);
if($unfit < $best || !$i) {
$best=$unfit;
$best_i=$i;
}
}
if($best_i>0) $parent[0]=$parent[$best_i];
$iters++;
print("Generation $iters, score $best: $parent[0]\n");
} while($best);

View file

@ -4,7 +4,7 @@ constant alphabet = 'A'..'Z',' ';
constant C = 100;
sub mutate { $^string.comb.map({ rand < mutate_chance ?? alphabet.pick !! $_ }).join }
sub fitness { [+] $^string.comb Zeq target.comb }
sub fitness { [+] $^string.comb Zeq state @ = target.comb }
loop (
my $parent = alphabet.roll(target.chars).join;

View file

@ -0,0 +1,60 @@
Option Explicit
Private Sub Main()
Dim Target
Dim Parent
Dim mutation_rate
Dim children
Dim bestfitness
Dim bestindex
Dim Index
Dim fitness
Target = "METHINKS IT IS LIKE A WEASEL"
Parent = "IU RFSGJABGOLYWF XSMFXNIABKT"
mutation_rate = 0.5
children = 10
ReDim child(children)
Do
bestfitness = 0
bestindex = 0
For Index = 1 To children
child(Index) = FNmutate(Parent, mutation_rate, Target)
fitness = FNfitness(Target, child(Index))
If fitness > bestfitness Then
bestfitness = fitness
bestindex = Index
End If
Next Index
Parent = child(bestindex)
Debug.Print Parent
Loop Until Parent = Target
End
End Sub
Function FNmutate(Text, Rate, ref)
Dim C As Integer
Dim Aux As Integer
If Rate > Rnd(1) Then
C = 63 + 27 * Rnd() + 1
If C = 64 Then C = 32
Aux = Len(Text) * Rnd() + 1
If Mid(Text, Aux, 1) <> Mid(ref, Aux, 1) Then
Text = Left(Text, Aux - 1) & Chr(C) & Mid(Text, Aux + 1)
End If
End If
FNmutate = Text
End Function
Function FNfitness(Text, ref)
Dim I, F
For I = 1 To Len(Text)
If Mid(Text, I, 1) = Mid(ref, I, 1) Then F = F + 1
Next
FNfitness = F / Len(Text)
End Function