Ala Qumsieh wrote:
John Porter writes:
The class is hard-wired to only handle individuals which are
bitvectors. That is unnecessarily restrictive.
Is it really restrictive? ... if the user wants more than a single bit to
represent a given feature, then he/she can still use the module the way it
is, but will have to do some manual high level grouping of the bits to get
the information needed.
Yes, it is restrictive. As a simple example: let's say I have a feature
which can have 128 distinct values. I need to allocate 8 bits for that,
which means that about 50% of the possible values obtained by
mutation/crossover will be invalid.
More critically, it means that the probability of mutating that feature
will not be m, but actually 1-((1-m)^b); that is, the probability is
"compounded" by the number of bits in the feature.
Similar predicament holds for crossover as well.
Another issue:
Currently you're doing multi-point crossover and considering the
invidual as a vector. These two are not mutually necessary.
If one desires multi-point crossover, the individual can be an unordered
set of features. OTOH, often we want the individual to be a vector so
that we can do 1- or 2-point crossover, exploiting (or just exploring :-)
Building Block effects.
This leads me to think that maybe a multidimentional
bit vector can be implemented instead of the single dimentional one I have
right now.
As long as you do multi-point crossover, you already have that.
What other representations can be used for the genetic string other than bit
vectors?
Anything symbolic.
Just because you *could* shoehorn it into a bitvector representation
doesn't mean you *should*. ;-)
Let me see if I understand you correctly. I should have an
AI::Genetic::Individual class that handles the representation of each
individual.
Well, if you want to go OO (which is what I would do), you could make
AI::Genetic::Individual a base class for things like
AI::Genetic::BitvectorIndividual.
It also implements all the evolutionary methods.
If you mean mutate/crossover/fitness -- yes.
So, a default strategy would be to evolve each generation according to the
current process (namely selection -> crossover -> mutation). ...
Well, if you want to make it a default, I guess that's fine.
I think it would be sufficient to make it one of the predifined strategies
which the user can simply name.
Btw, I might suggest that genetic operations also be factored out from
the representation class(es) into Strategies, since you can have many
different ways of doing mutation/crossover/fitness on a bitvector.
I thought maybe I can improve the speed of the processing by eliminating
duplicates, but maybe it's not such a good idea. After all, if there are
many individuals with the same genes, then there is a reason for this and
this will favour them more in keeping their genes alive in generations to
come.
Precisely. :-)
I'd be happy to help you code this stuff up, if you want.
--
John Douglas Porter
I no longer love the color of your sweaters.