Here is how I understand the terminology, so
that we don't talk past each other. Please let me
know if I get it wrong.
A 'gene' has a 'name' and a 'value'. A set of
genes values is a 'person'. This person
has a single number for 'fitness'. Fitness can
be computed from the values of the genes.
The end result of evolution process is the
most fit person.
In this problem a person represents an entire schedule.
The genes are the individual schedule entries.
There are stringent restrictions on the data types
for the genes. One hard part of using a genetic
algorithms is the work needed to map the problem space
into the limited data types of the GA package.
The fitness evaluator looks at the person
and sees how well it satisfies the student
sign-ups and other constraints. Efficienty
of the fitness evaluator is important.
Any tests that disqualify a particular
person can be checked first. In these cases the fitness
is zero and the routine can use a short-cut
return, without evaluating all the other fitness
criteria.
I tried your first suggested solution, where
the genes represent the timeslots for each
classroom, and the values are the class
for that slot. This way of doing it moves the
complexity away from the mapping problem into
the fitness evaluation function, where I think
it is much easier to deal with.
In my trivial example a single instructor
sequentially teaches two different classes out of
a possible three classes. One class will be
cancelled due to 'lack of interest'.
The students can sign up for one or two classes and can
optionally specify a priority of 1 or 2. The three
classes are called 'genetic', 'neural', and 'fuzzy'.
use strict;
use warnings;
use AI::Genetic;
my %signup;
$signup{bob}{genetic} = 2;
$signup{ted}{genetic} = 1;
$signup{alice}{genetic} = 1;
$signup{carol}{genetic} = 0;
$signup{joe}{genetic} = 0;
$signup{biff}{genetic} = 0;
$signup{sneezy}{genetic}= 0;
$signup{bob}{neural} = 0;
$signup{ted}{neural} = 0;
$signup{alice}{neural} = 1;
$signup{carol}{neural} = 2;
$signup{joe}{neural} = 1;
$signup{biff}{neural} = 1;
$signup{sneezy}{neural}= 0;
$signup{bob}{fuzzy} = 0;
$signup{ted}{fuzzy} = 1;
$signup{alice}{fuzzy} = 0;
$signup{carol}{fuzzy} = 1;
$signup{joe}{fuzzy} = 0;
$signup{biff}{fuzzy} = 0;
$signup{sneezy}{fuzzy}= 2;
my $generations= 0;
sub fitness
{
my ($classes)= @_;
my $class1= $classes->[0];
my $class2= $classes->[1];
return 0 if $class1 eq $class2;
my $fitness=0;
foreach my $student_name (keys %signup)
{
if ($signup{$student_name}{$class1} > $signup{$student_name}{$clas
+s2})
{
$fitness += $signup{$student_name}{$class1};
}
else
{
$fitness += $signup{$student_name}{$class2};
}
}
return $fitness;
}
my $ga = new AI::Genetic(
-fitness => \&fitness,
-type => 'listvector',
-population => 500,
-crossover => 0.9,
-mutation => 0.01,
-terminate => sub { $generations++;
return 1 if $generations > 100;
return 0 },
);
$ga->init([
[qw/genetic neural fuzzy/ ],
[qw/genetic neural fuzzy/ ],
]);
$ga->evolve('rouletteTwoPoint', 100);
print "Best score = ", $ga->getFittest->score, ".\n";
print "Best genes = ", join(' ',$ga->getFittest->genes), ".\n";
It should work perfectly the first time! - toma
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.