sub sortIndividuals {
my ($self, $list) = @_;
return [sort {$b->score <=> $a->score} map {$_->score;$_} @$list];
}
Update: You also have to change the two sort commands in AI/Genetic/OpSelection.pm if you want this to work reliably for small populations. In both cases, change
sort {$b->score <=> $a->score}
to
sort {$b->score <=> $a->score} map {$_->score;$_}
An alternative to patching AI::Genetic internals is to get a version of perl that doesn't suffer from the bug described here: http://www.nntp.perl.org/group/perl.perl5.porters/37481. To my knowledge, such a version of perl does not yet exist, but hey, you are merlyn.
Once that's done, you can try my approach. However, to make it easier to understand and compare side-by-side with your original approach, I rewrote your approach so that both ways of coding this had as much identical code as possible. This means that neither approach is implemented as cleanly or as efficiently as it could be - the goal was side-by-side comparison, not efficiency. In fact, the two scripts are now so similar that I'm just going to present yours as I recoded it and then explain how to transform it into mine:
Now, to change that into my approach, where the genes represent class priorities, first change the setup code to:
my $ga = AI::Genetic->new
(
-fitness => \&my_fitness,
-type => 'rangevector',
-terminate => \&my_terminate
);
$ga->init([map {[0,100]} @CLASSES]);
Then, change the make_config sub:
sub make_config {
my (@genes) = @_;
# sort classes in order by genes:
use Data::Dumper;
my (@order) = sort {$genes[$a] <=> $genes[$b];} (0..$#CLASSES);
my (@sclasses) = @CLASSES[@order];
push(@sclasses, (qw{XXX}) x ($SLOTS * $ROOMS));
my ($config) = [];
for my $s (0..$SLOTS-1) {
push @$config, [];
for my $r (0..$ROOMS-1) {
my $i=0;
while (!is_acceptable($sclasses[$i],$s,$r,$config)) {$i++;}
push @{$config->[-1]}, splice(@sclasses,$i,1);
}
}
$config;
}
And that's it.
The interesting thing is that this priority-driven approach converges almost instantly with the scoring function you supplied - the first or second generation usually has a configuration that scores at 20.5 or 21. (21 is the max. possible here)
I would be interested to know what more advanced scoring functions you come up with later and whether this priority-driven approach ends up being significantly better in practice than your initial approach of having a gene for each room/slot combination.
--
@/=map{[/./g]}qw/.h_nJ Xapou cets krht ele_ r_ra/;
map{y/X_/\n /;print}map{pop@$_}@/for@/
|