in reply to Brute force perl

Ok. A semi-working GA implementation. This fitness function was the best I could think of, and suggestions are very welcome. Also, sorry for not DRYing the code. That's what happens when you get me excited :)

You will, again, want to redirect stderr to /dev/null :). With 50 generations, it took about 17 seconds wall-clock time to run on my machine.

Update: Hmm. One thing I notice is that things like '<text>' or q~<text>~ get generated a lot. I've subtracted points in my fitness function for that sort of ``cheating'', but as I do so, the GA just ``finds'' more ways to ``cheat''. As it is, unless I can think of some more sophisticated fitness function (one that somehow calculates actual usefulness of the code), the current one will just keep growing as I try to (clumsily) parse the perl. (And we all know that goes. It isn't "Nothing but perl and jagh can parse Perl", is it? :)

Update2: Fixed the mess that was the call to $ga->init(). Thank you, jdporter.

Update3: Tweaked the fitness function. I'm also putting the code at my site, to avoid spamming PM with trivial updates as I play. Anything significant will end up back here.

#!/usr/bin/perl -w use strict; sub fitness { my ($chars) = @_; my $s = join '', @$chars; my $f = system('perl', '-ce', $s); ## zero and an immediate return if it fails to compile if ($f == 0) { $ret = 10; } else { return 0; } ## quotes and POD is cheating. Comment char isn't included, ## so don't bother with it. $ret-=10 if (substr($s, 0, 1) eq '='); #subtract if it's a POD $ret-=10 if ($s =~ /^q(.).*?(\1)$/); #q() string? $ret-=10 if ($s =~ /^([`'"]).*(\1)$/); # quoted strings or backtick +s ## Spaces at the start and end are a lesser form of cheating $ret-=2 if ($s =~ /^ /); $ret-=2 if ($s =~ / $/); $ret++ if ($s =~ /\w \w/); # space separated words are kinda cool. if ($ret < 0) { $ret = 0 }; return $ret; } use AI::Genetic; my $ga = new AI::Genetic( -fitness => \&fitness, -type => 'listvector', ); my @chars = ( 32..34,36..64,91..126 ); $_ = chr($_) for @chars; $ga->init([ map { [@chars] } 1..20 ]); $ga->evolve('randomTwoPoint', 50); my $chars = $ga->getFittest->genes();; print "Best score = ", $ga->getFittest->score(), ".\n"; my $s = join '',@$chars; print "$s\n";

Replies are listed 'Best First'.
Re: GA perl (was: Brute force perl)
by jdporter (Paladin) on Jun 12, 2007 at 19:50 UTC

    Ech...

    my @chars = ( 32..34,36..64,91..126 ); $_ = chr($_) for @chars; $ga->init([ map { [@chars] } 1..20 ]);